snowflake getting everything except the last part SQL - sql

When using snowflake I need everything except the last part of these:
for example1 :
xxx | YYY | XXX | asda | dasd12 | adasda
I just need
xxx | YYY | XXX | asda | dasd12
example2:
32131| Y\ZYY | XXX | asda | dasd12 | 213131 | adsadfd
I just need
32131| Y\ZYY | XXX | asda | dasd12 | 213131
can anyone help me please?
The number of pipes can be random
I need everything except the last pipe and whatever there is after

there may be prettier ways of doing this but this should work (the functions to use are in caps)
REVERSE the string
Find the POSITION of the first pipe
Get the RIGHT portion of the string from that pipe position
REVERSE the result

You can split the string to array, slice it, and stitch it back as string
select array_to_string(array_slice(split(your_column,'|'),0,-1),'|')
In case you fancy regex
select regexp_substr(your_column,'(.*)[|]',1, 1, 'e')

Related

How to get rid of response headings in Google Sheets?

I read an API with Google Sheets and want to get results similarly to this:
+-------+-------------------+-----------------+
| Input | Formula | Result column |
+-------+-------------------+-----------------+
| 11 | =MyApiFormula(A2) | responseValue11 |
+-------+-------------------+-----------------+
| 22 | =MyApiFormula(A3) | responseValue22 |
+-------+-------------------+-----------------+
But the API is a bit strange and puts always a header row into response. With it, the response of the first formula looks like:
+-------+-------------------+-------------------+
| Input | Formula | Result column |
+-------+-------------------+-------------------+
| 11 | =MyApiFormula(A2) | responseHeading11 |
+-------+-------------------+-------------------+
| | | responseValue11 |
+-------+-------------------+-------------------+
and the second formula (=MyApiFormula(A3)) doesn't work at all - sure, because it is forced to write into cells with already existing data.
I guess, this heading row can be avoided with a =QUERY formula with INDEX and an offset -1 - but I fail with correct syntax.
Could somoebody point me to the correct writing?
QUERY syntax would be:
=QUERY(...; "offset 1"; 0)
substitute dots for your formula

How can I combine Postgresgl's ArrayField ANY option with LIKE

I'm trying to filter a queryset on the first characters of an element in an ArrayField in postgresql.
Data
--------------------
| id | registration_date | sbi_codes |
| 1 | 2007-11-13 | {9002, 1002, 85621} |
| 2 | 2010-10-11 | {1002, 9022, 9033 |
| 3 | 2019-02-02 | {9001, 8921} |
| 4 | 2012-02-02 | {120} |
I've tried the following (which obviously don't work), but I think clearly indicates what I'm trying to achieve.
select count(*)
from administrations_administration
where '90' = left(any(sbi_codes),2)
or
select count(*)
from administrations_administration
where '90%' like any(sbi_codes
So the sbi_codes can be for example 9002 or 9045, And I'm trying to filter all the records that contain an element that starts with 90.
expected result
____
| count | sbi_codes |
| 3 | 90 |
Thanks!
The thing on the left hand side of LIKE is the string, in which % is just a %. The thing on the right hand side is the pattern, in which % is a wildcard. Using ANY does't change these semantics, the pattern still goes the right.
To solve this, you could create your own operator which is like LIKE, but has its arguments reversed.

Reverse Split_part SQL

Is there a way to there a way to delimit data and select the 2nd to last substring
Sample Input:
*------------------------------------*
| Name |
*------------------------------------*
|Mike__NYC_180x9_School |
|Oak_Ann_1_LA_1x190_Uni |
|Tiger_King_Al_car_12_10x15_sample |
*------------------------------------*
Desired Output:
*--------------*
|Account number|
*--------------*
|180x9 |
|1x190 |
|10x15 |
*--------------*
reverse the string then take the second word and then reverse it again.
select reverse(split_part(reverse(Name),'_',2));

Generate rows from input array

Let's assume I have a table with many records called comments, and each record includes only a text body:
CREATE TABLE comments(id INT NOT NULL, body TEXT NOT NULL, PRIMARY KEY(id));
INSERT INTO comments VALUES (generate_series(1,100), md5(random()::text));
Now, I have an input array with N substrings, with arbitrary length. For example:
abc
xyzw
123456
not_found
For each input value, I want to return all rows that match a certain condition.
For example, given that the table includes the following records:
| id | body |
| -- | ----------- |
| 11 | abcd1234567 |
| 22 | unkown12 |
| 33 | abxyzw |
| 44 | 12345abc |
| 55 | found |
I need a query that returns the following result:
| substring | comments.id | comments.body |
| --------- | ----------- | ------------- |
| abc | 11 | abcd1234567 |
| abc | 44 | 12345abc |
| xyzw | 33 | abxyzw |
| 123456 | 11 | abcd1234567 |
So far, I have this SQL query:
SELECT substrings, comments.id, comments.body
FROM unnest(ARRAY[
'abc',
'xyzw',
'123456',
'not_found'
]) AS substrings
JOIN comments ON comments.id IN (
SELECT id
FROM comments as inner_comments
WHERE inner_comments.body LIKE ('%' || substrings || '%')
);
But the database client gets stuck for more than 10 minutes. And I missing something about joins?
Please note that this is a simplified example of my problem. My current check on the comment is not a LIKE statement, but a complex switch-case statement of different functions (fuzzy matching).
The detour with the IN is unnecessary and unless the optimizer can rewrite this and it likely cannot, adds overhead. Try if it gets better without.
SELECT un.substring,
comments.id,
comments.body
FROM unnest(ARRAY['abc',
'xyzw',
'123456',
'not_found']) un (substring)
INNER JOIN comments
ON comments.body LIKE ('%' || un.substring || '%');
But still indexes cannot be used here because of the wildcard at the beginning. You might want to look at Full Text Search and see what options you have with it to improve the situation.
Basically you are performing FULLTEXT search in a column that most likely doesn't have a FULLTEXT index.
A first step you could try would be to have your column "body" FULLTEXT indexed. See details here and then perform the search using CONTAINS but, quite honestly, since you want to perform fuzzy matching you cannot rely on SQL server to perform the search - it would just not work properly. You will need an indexing service such as ElasticSearch, CloudSearch, Azure Search, etc

Oracle SQL regex extraction

I have data as follows in a column
+----------------------+
| my_column |
+----------------------+
| test_PC_xyz_blah |
| test_PC_pqrs_bloh |
| test_Mobile_pqrs_bleh|
+----------------------+
How can I extract the following as columns?
+----------+-------+
| Platform | Value |
+----------+-------+
| PC | xyz |
| PC | pqrs |
| Mobile | pqrs |
+----------+-------+
I tried using REGEXP_SUBSTR
Default first pattern occurrence for platform:
select regexp_substr(my_column, 'test_(.*)_(.*)_(.*)') as platform from table
Getting second pattern occurrence for value:
select regexp_substr(my_column, 'test_(.*)_(.*)_(.*)', 1, 2) as value from table
This isn't working, however. Where am I going wrong?
For Non-empty tokens
select regexp_substr(my_column,'[^_]+',1,2) as platform
,regexp_substr(my_column,'[^_]+',1,3) as value
from my_table
;
For possibly empty tokens
select regexp_substr(my_column,'^.*?_(.*)?_.*?_.*$',1,1,'',1) as platform
,regexp_substr(my_column,'^.*?_.*?_(.*)?_.*$',1,1,'',1) as value
from my_table
;
+----------+-------+
| PLATFORM | VALUE |
+----------+-------+
| PC | xyz |
+----------+-------+
| PC | pqrs |
+----------+-------+
| Mobile | pqrs |
+----------+-------+
(.*) is greedy by nature, it will match all character including _ character as well, so test_(.*) will match whole of your string. Hence further groups in pattern _(.*)_(.*) have nothing to match, whole regex fails. The trick is to match all characters excluding _. This can be done by defining a group ([^_]+). This group defines a negative character set and it will match to any character except for _ . If you have better pattern, you can use them like [A-Za-z] or [:alphanum]. Once you slice your string to multiple sub strings separated by _, then just select 2nd and 3rd group.
ex:
SELECT REGEXP_SUBSTR( my_column,'(([^_]+))',1,2) as platform, REGEXP_SUBSTR( my_column,'(([^_]+))',1,3) as value from table;
Note: AFAIK there is no straight forward method to Oracle to exact matching groups. You can use regexp_replace for this purpose, but it unlike capabilities of other programming language where you can exact just group 2 and group 3. See this link for example.