Getting unique entries from a columns generated by matching regexp in SQL - mysql

I have a table which i am using to query and getting its one column which matches regular expression which is (\/.+\/\?).
Content of the resulted column is like:
/Anything here/?
Example output:
\abc\cdf\?....
\ab\?....
\abc\cdf\?....
\sb\?....
where '....' can be anything
Desired result i want is unique values before \? such that rows with duplicate regexp matched content are shown once only like here (\abc\cdf\?.... showing twice instead of onece)
\abc\cdf\?....
\ab\?....
\sb\?....
OR
\abc\cdf\?
\ab\?
\sb\?
I have looked very much but couldn't find anything there is regexp_substr in oracle but that is not working in SQL.
Please if someone could help me with the sql query that would be awesome.

If you want everything before the last \, then you can use substring_index() and some string manipulation:
select substring_index(col, '\\',
length(col) - length(replace(col, '\\', ''))
) as firstpart,
count(*)
from table t
group by substring_index(col, '\\',
length(col) - length(replace(col, '\\', ''))
);

Related

How to change MySQL GROUP_CONCAT to PostgreSQL string_agg?

I'm migrating some MySQL code to Postgres and having a heck of a time converting the following line:
GROUP_CONCAT(
DISTINCT id,':',foo,':',bar ORDER BY id
) as id,
This results in a comma separated list of strings like:
id:foo:bar,id2:foo2:bar2
The 'DISTINCT' is there to avoid duplicates.
I've read the equivalent of GROUP_CONCAT in Postgres is string_agg, but I can't figure out how to make it work the same way.
Edit: I may have almost answered my own question. I came up with the solution of using CONCAT. The problem with this is that now sorting is done by the concatenated string rather than by the id:
string_agg(DISTINCT CONCAT(
id::text, ':', foo, ':', bar, ':'
), ',') as id
If I try to add 'ORDER BY id' I get an error.
You can do something like below.
select
string_agg(DISTINCT CONCAT(
id::text, ':', foo, ':', bar, ':'
), ',') as id from (select * from table t order by id) as al

MySql Substring Index, Find and replace characters

I need to find the first and second "_" and extract whatever is between.
example data
doc_856_abc_123
doc_876_xyz_999
So far I have the following substring query. But I need help
select SUBSTRING_INDEX( column, '_', 2 )
It is outputting
doc_856
doc_867
How do I combine the above query to maybe another substring go get the desired results. Which would be.
856
867
Just apply SUBSTRING_INDEX again on the resulted string
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(column, '_', 2 ), '_', -1)

Trying to apply regex to column in select query

I have JSON stored in a MySQL database (version 5.6.17) that I'm trying to regex into a column to retrieve a list of campaign IDs. My query is as follows:
SELECT JSON REGEXP '"id":([0-9]*)' AS id
FROM PROD_APPNEXUS.dimension_json_creatives;
where JSON is a column containing the data I need to parse as ID. I know REGEXP can be used for strings in SELECT queries (i.e. SELECT 'foobar' REGEXP '([a-z]+)' AS foobar) but can columns be pattern matched in the same way?
Would there be a way to cast the JSON column as string and then regex?
Any help would be appreciated!
Thanks,
Sam
You can use replace and substring_index to split your column, like this;)
SELECT replace(substring_index(JSON, ':', -1), '"', '') AS id
FROM PROD_APPNEXUS.dimension_json_creatives;
when I run sql below return aaaa,
select replace(substring_index('"id":"aaaa"', ':', -1), '"', '');
I assumed your JSON's value does not exist :.

MySQL find common path

I want to find common parent folder in my table images with field path.
For example, in my table i have for this table 6 rows.
1 c:\images\site1\root\img\logo.png
2 c:\images\site1\root\resource\test1.png
3 c:\images\site1\root\resource\test2.png
4 c:\images\site1\root\resource\test3.png
5 c:\images\site1\root\images\background.png
And I want to have "root" folders:
c:\images\site1\root\img\
c:\images\site1\root\resource\
c:\images\site1\root\images\
What is the SQL request to get this, please?
Many thanks.
This can be a bit tricky. If you know that the path does not share the name of the file, you could replace the last part with an empty string:
select distinct replace(path, substring_index(path, '\\', -1), '')
However, this may not always be true.
What you want is everything before the last occurrence of \\. Here is a method using substring_index():
select distinct substring_index(path, '\\',
length(path) - length(replace(path, '\\', '')
)
The difference in lengths is simply counting the number of separator characters in the string. If the path has one separator (i.e. 'a\b'), then the argument to substring_index() is 1, which is what you want.

I would like to replace the text in a column from "300-21-2" to "300-21-02" with one query

Is there an easy way to replace all the text in a VARCHAR 255 column from "300-21-2" to "300-21-02" with one query?
Thank you.
This is basic SQL
UPDATE tablename
SET columnname = '300-21-02'
WHERE columnname = '300-21-2'
If the pattern is always the same NNN-NN-N then what you need is:
update tablex
set column = concat( substr(column,1,7), lpad(substr(column,8),2,'0') )
see it at fiddle:
http://sqlfiddle.com/#!2/f59fe/1
EDIT As the op showed the pattern
update tablex
set column = CONCAT(
substring_index(col, '-',1), '-',
lpad(substring_index(substring_index(col, '-',-2), '-', 1),2,'0'), '-',
lpad(substring_index(col, '-',-1), 2, '0') )
If you like to convert the first set like 300 to 00300 as your pattern you add the lpad as this: lpad(substring_index(col, '-',1),5,'0')
This should be a lot easier if mysql has support to regex replace, but as it hasnt you have to work with the strings:
from this value: '300-02-1'
from substring_index(col, '-',1) I'm getting: 300
from substring_index(substring_index(col, '-',-2), '-', 1) I'm getting 02 I did this because just put the substring_index(col, '-',2) gave me 300-02 so, i got it from right to left (-2) then i get the first
and substring_index(col, '-',-1) it bring me 1 because it gets the value from right to left
Then I just concatenate it all formatting the ones I want.