I have strings which have a JSON-like format, including:
..."id":"500", ..., "id":"600", ...
I need to parse the second id out of the column. I found lots of answers using substring_index, however, I need to get the string after the 2nd (of potentially n) occurrences and not the string before to parse out the ID.
Is there a nice solution?
To find the substring of a column "some_column" occurring after the nth
occurrence of a target string,
SELECT
SUBSTRING(some_column, CHAR_LENGTH(SUBSTRING_INDEX(some_column, <target_string>, <n>)) + <length of target string + 1>)
FROM some_table
-- or if you want to limit the length of your returned substring...
SELECT
SUBSTRING(some_column, CHAR_LENGTH(SUBSTRING_INDEX(some_column, <target_string>, <n>)) + <length of target string + 1>, <desired length>)
FROM some_table
For this question, the form would be:
SELECT
SUBSTRING(col, CHAR_LENGTH(SUBSTRING_INDEX(col, '"id":"', 2)) + 7)
FROM `table`
For now I have:
SELECT substring_index(
substr(col, locate('"id":"', col, locate('"id":"', col) + 6) + 6),
'"',
1)
FROM table
Would love to see a "nicer" answer :-)
In Snowflake, this can be done as follows:
select
, split_part([field_name], '{separator}', {n-counter})
from
[table]
Note: {separator} and {n-counter} are inputs provided by the user. Snowflake requires apostrophes around {separator}.
Related
For e.g. If I have column entry as
'The only verdict is : Vendetta'
and the same column has another entry as
'I believe in : Harvey Dent'
and all I want to select via my query is 'Vendetta' and 'Harvey Dent' i.e. the string just after the : sign, how do I do it?
Can it be restricted to select upto a specific number of characters after the sign?
If you only have one : in your string, you can give a look at SUBSTRING_INDEX:
SELECT
col,
SUBSTRING_INDEX(col, ':', -1)
FROM
tablename
or you can use SUBSTRING with LOCATE:
SELECT
col,
SUBSTRING(col FROM locate(':', col)+1)
FROM
tablename
WHERE
col LIKE '%:%'
(in your example you probably need to substitute ':' with ' : ' and +1 with +3)
I am trying to remove everything before the third / in a column. For example: If there is a URL in the coloumn such as
http://www.example.com/example1/example2?=testest123
I would like to remove everything (not including the thrid slash) so i will be left with something like this
/example1/example2?=testest123
I have tried using this but it only removes everything from first "/" and i can't work out how to get it to count to the third then remove.
update table
set column2 = substring(column1, instr(column1, '/') + 1);
Thanks.
To start, you can use the SUBSTRING_INDEX function to get the characters of the string leading up to the third (or fourth slash, in your example) like this:
SELECT SUBSTRING_INDEX(val, '/', 4)
FROM myTable;
You can use the REPLACE() function to remove that substring by replacing it with an empty string, like this:
SELECT REPLACE(val, SUBSTRING_INDEX(val, '/', 4), '')
FROM myTable;
Now, to update your table, simple rewrite the query to set the value to the one above:
UPDATE myTable
SET val = REPLACE(val, SUBSTRING_INDEX(val, '/', 4), '');
NOTE that if there are less than four occurrences of a forward slash, SUBSTRING_INDEX will return the entire string, and therefore completely replacing the entire string by an empty value so you should be very careful when preforming this update.
Here is an SQL Fiddle example with your sample text, and one that I wrote with fewer slashes to demonstrate the last point.
That's a bit messy, but you can try this :
UPDATE table
SET column2 = SUBSTRING(column1,
LOCATE('/', column1,
LOCATE('/', column1,
LOCATE('/', column1))+1)+1)
I'd like to extract the number between NUMBER and ;. So far I can extract the data up to the number, but I don't want anything after the number. e.g.,
SELECT
SUBSTRING(field, LOCATE('NUMBER=', rrule) + 7)
FROM table
Data field:
DATA:PASS=X12;NUMBER=331;FIELD=1
DATA:PASS=X12;NUMBER=2;FOO=BAR;FIELD=1
Desired Output:
331
2
You can use a combination of SUBSTRING_INDEX functions:
SELECT
SUBSTRING_INDEX(
SUBSTRING_INDEX(field, 'NUMBER=', -1),
';',
1)
FROM
tablename
Please see an example fiddle here.
The inner SUBSTRING_INDEX will return everything after the NUMBER= string, while the second will return everything before the ; returned by the inner function.
I am sorry if this question is too noob.
I have a jason array stored in a column, and I wonder if possible to read one of array and sort it out.
Like say if this is the data in column A, {'class':'beatiful','name':'wonderful'}. I want to sort 'class' as ASC.
How can I implement sql sentence? May I have any example that I reference?
Or what kind of format of data stored can do this kind of request expect adding new column?
Thank you very much.
It's not pretty, but this is basically splitting your JSON string and sorting by the class:
select *
, substring_index(substring_index(
replace(substr(A, 2, char_length(A) - 2), '\':\'', '\',\'')
, ','
, find_in_set('\'class\'', replace(substr(A, 2, char_length(A) - 2), '\':\'', '\',\'')) + 1
), ',', -1) as SortItem
from MyTable
order by SortItem;
Here is a demo SqlFiddle.
You might have to change delimiters according to quotes or apostrophes in your JSON.
Also, as the comments have pointed out, this is ugly because you're using your relational database in a non-relational manner.
Doesn't JSON use double quotes?
Try some String functions to extract it. For example, you could find the position of "class". Then, look for the next opening double quoite, which would be the start of the value. Then, look for another, which would be the end of the value. Finally, get the sub-string out.
Pseudo code would look like this:
P1 = Position of class key = LOCATE('"class"', COL_A)
P2 = Position of open quote for value = LOCATE('"', COL_A, P1 + 7 )
P3 = Position of Close quote for value = LOCATE('"', COL_A, P2 + 1)
Substr that is the value = SUBSTRING(COL_A, P2, P3 - P2)
Expanding that:
SUBSTRING(COL_A, LOCATE('"', COL_A, LOCATE('"class"', COL_A)+ 7 ), LOCATE('"', COL_A, LOCATE('"', COL_A, P1 + 7 ) + 1) - LOCATE('"', COL_A, LOCATE('"class"', COL_A) + 7 ))
I have not run it on MySql to check, but you get the idea. Also, you might want to change it so that you can handle situations where the string "class" appears inside some other value field.
Once you have an expression that extracts the value, you can sort on it.
I'm trying to select distinct substring values of a field and count the number of instances of a char in that selection.
I've found this wonderful post which answers half of it.
So, so far, i can count the instances of a char in my field, it works great. Now the even harder part, what if i select a piece of string using :
SELECT DISTINCT SUBSTRING_INDEX(my_field, '-', -1) AS chunk
In this case i'm only selecting the last part of the string (everything after the last'-'). How can i apply this formula to chunk (trying to count the number of instances of '_' in the new string ? :
(LENGTH(chunk) - LENGTH(REPLACE(chunk, '_', ''))) / LENGTH('_')
I know i shoud be using HAVING to make operation on chunk as it's not a real field, but how can i do something like :
SELECT DISTINCT SUBSTRING_INDEX(my_field, '-', -1) AS chunk, (LENGTH(chunk) - LENGTH(REPLACE(chunk, '_', ''))) / LENGTH('_') AS total FROM my_field HAVING total < 2
The problem here is that i can't use 'chunk' in the last part since it's not a field..
The problem here is that i can't use 'chunk' in the last part since it's not a field..
Replace 'chunk' in the last part with
SUBSTRING_INDEX(my_field, '-', -1)
Don't know what's the problem?