MySQL find common path - mysql

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.

Related

Capture groups in mysql regexp

I have a table with a varchar column that represents a path. I want to search for rows that have a path that follow a pattern like name.name[*] where name can be anything. I am looking for repeated strings contained anywhere in the path column that are separated by a period and have a square bracket after them.
This seems to call for Regexp, so through python I have something like https://regex101.com/r/apS20a/4
However, trying to implement this with MySQL Regexp is not working. I have been able to translate the shorthand into REGEXP '([A-Za-z_]+).(\1[[0-9]+])', but it seems that MySql Regex does not support capture groups. Is there a way to accomplish what I am trying to do with mysql regexp? Thank you
I don't think that MySQL supports capture groups. But if you only have one example of .name[ in the string between the first . and the first [, you can hack your way around it. This is not a general solution, just a specific approach in this case.
You can get the name with:
select substring_index(substring_index(url, '[', 1), '.', -1) as name
And then incorporate this into a regular expression:
select t.*
from (select t.*,
substring_index(substring_index(url, '[', 1), '.', -1) as name
from t
) t
where url like concat('%', name, '.', name, '[%');
This just uses like instead of regexp, because [ and . are regular expression wildcards. Of course, this assumes that name does not have _ or %.
EDIT:
Here is a method that actually identifies when this occurs -- and works even if there are multiple patterns.
The idea is to construct the regular expression based on what happens between the . and [ -- and then to apply it. Delightfully self-referential:
select t.*,
(url regexp regex)
from (select t.*,
substr(regexp_replace(url, '[^.]*[.]([^\\[]*)\\[[^.]*', '|$1[.]$1\\\\['), 2) as regex
from (select 'abcde.de[12345.345[ABC' as url union all
select 'abcdefdef[[[[..123.124['
) t
) t;
Here is the above in a db<>fiddle.

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)

How to match strings that have exactly 2 slashes in MySQL

I have a database with a lot of paths, and I need to find all the paths that have only 2 levels, not more not less.
For example, I need a query that will find string matching the following structure:
folder/folder/file.ext
But not:
folder/file.ext and not folder/folder/folder/file.ext or anything longer
My guess here is to use REGEX and match strings that precisely have 2 slashes / but I don't know how to formulate the expression, something like:
SELECT `name` FROM `table` WHERE `name` REGEXP '????'
In my case I need to find 2 slashes and is very specific but ideally this answer will be useful for anybody looking for 3 or X number of slashes or any other character repeated on the string.
The simplest method uses like:
where name like '%/%/%' and
name not like '%/%/%/%'
Doing this as a regular expression is tricky. But here is another method:
where length(name) - length(replace(name, '/', '')) = 2
As a regular expression:
where name regexp '^([^/]*[/]){2}[^/]*$'
So it is possible, although perhaps less scrutable.
WHERE LENGTH(name) = 2 +
LENGTH(REPLACE(name, '/', ''))

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

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, '\\', ''))
);

How to get left substring in mysql

it sems odd, but I can't find a quick and simple way to solve my task:
I have many rows with different absolute paths like:
/application/themes/openbank/images/prettyPhoto/light_square/default_thumbnail.gif
/application/themes/openbank/images/default_thumbnail.png
/application/themes/openbank/images/prettyPhoto/light_square/a_s.pdf
and I want to split them in
parent_path ("e.g. /application/themes/openbank/images/prettyPhoto/light_square/")
file_name ("e.g. default_thumbnail.gif")
NB: file name's lenght and number of separators is variable.
With
SUBSTRING_INDEX('/application/themes/openbank/images/prettyPhoto/light_square/default_thumbnail.gif', '/', -1)
I correctly get the file_name,
but I can't find a way to retrieve the left part.
I tried LEFT(), RIGHT(), and all other mysql's string function with no success
Linuxatico
Try below to get parent_path
select reverse(substring(reverse('/application/themes/openbank/images/prettyPhoto/light_square/default_thumbnail.gif'),instr(reverse('/application/themes/openbank/images/prettyPhoto/light_square/default_thumbnail.gif'),'/')))
select substr( path, 1, instr(path, substring_index( path, '/', -1)) - 1 ) as "PARENT_PATH", substring_index(path, '/', -1 ) as "FILE_NAME" from table1;
Another way would be the combination of LEFT, SUBSTRING_INDEX and CHAR_LENGTH:
My solution takes the left part of the string with length = length(absolute path) - length(file part).
SET #content = '/application/themes/openbank/images/prettyPhoto/light_square/default_thumbnail.gif';
SELECT
LEFT(
#content,
CHAR_LENGTH(#content) - CHAR_LENGTH(SUBSTRING_INDEX(#content, '/', -1))
);
See the three first answers working in this fiddle.
I'm sure there are some other ways too to get the desired result.