I have strings values such as the following in a column:
|333|,|331|
I want to perform a balanced string replacement as follows:
xxTM_333_TMxx,xxTM_331_TMxx
I have tried to do this with the REPLACE and CONCAT functions but didn't get the desired output.
For example:
SELECT REPLACE('|333|,|331|','|','xxTM');
This replaces one of the | symbols correctly in each case, but not its matched (balanced) counterpart.
How can I achieve this result in MySQL?
SET #st := '|333|,|331|';
SELECT
CASE WHEN #st LIKE '|%|' THEN
CONCAT(
'xxTM',
REPLACE(REPLACE(#st, '|,|', '_TMxx,xxTM_'), '|', '_'),
'TMxx')
END rep_st;
Please see fiddle here.
Related
I am trying a simple select statement with a variable. The statement works fine if I change the like concat_ws('%', #S, '%'); to a string. It seems that the select statement is not picking up the SET variable. Help would be much appreciated. I am using Mysql80 workbench.
SET #S = "product";
SELECT distinct idproducts FROM mgjtest.vorutaflamedsamheit
WHERE productname like concat_ws('%', #S, '%');
````````````````````````````````````````````````````````````````
Simply use CONCAT to ensure wildcards on either side of variable value. Otherwise, CONCAT_WS which uses first argument as separator returns double wildcards at the end of string which is equivalent to single wildcard and yields undesired results.
LIKE 'product%%'
LIKE 'product%'
However, CONCAT will return wildcards as you expect:
LIKE '%product%'
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.
I am trying to getting just the first two words on sql query, I am using the match: ^\w{2}- but with no success because nothing is coming to me, I need to get those values
BA, CE, DF, ES, GO, I don't know how can I do that, below some data example.
SC&Tipo=FM
SC&Tipo=Web
SC&Tipo=Comunitaria
RS&Tipo=Todas
RS&Tipo=AM
RS&Tipo=FM
RS&Tipo=Web
RS&Tipo=Comunitaria
BA-Salvador&Tipo=12horas
CE-Fortaleza&Tipo=12horas
CE-Interior&Tipo=12horas
DF-Brasilia&Tipo=12horas
ES-Interior&Tipo=12horas
ES-Vitoria&Tipo=12horas
GO-Goiania&Tipo=12horas
MG-ZonaDaMata/LestedeMinas&Tipo=12horas
MG-AltoParanaiba&Tipo=12horas
MG-BeloHorizonte&Tipo=12horas
MG-CentroOestedeMinas&Tipo=12horas
Query: SELECT * FROM tabel WHERE filter REGEXP '^\w{2}-'
EDIT SOLVED:
To solve the query should be:
SELECT SUBSTRING(column, 1, 2) AS column FROM table WHERE column REGEXP '^[[:alnum:]_]{2}-'
MySQL doesn't support the character class \w or \d. Instead of \w you have to use [[:alnum:]]. You can find all the supported character classes on the official MySQL documentation.
So you can use the following solution using REGEXP:
SELECT *
FROM table_name
WHERE filter REGEXP '^[[:alnum:]]{2}-'
You can use the following to get the result with regular expression too, using REGEXP_SUBSTR:
SELECT REGEXP_SUBSTR(filter, '^[[:alnum:]]{2}-')
FROM table_name
WHERE filter REGEXP '^[[:alnum:]]{2}-';
Or another solution using HAVING to filter the result:
SELECT REGEXP_SUBSTR(filter, '^[[:alnum:]]{2}-') AS colResult
FROM table_name
HAVING colResult IS NOT NULL;
To get the value before MySQL 8.0 you can use the following with LEFT:
SELECT LEFT(filter, 3)
FROM table_name
WHERE filter REGEXP '^[[:alnum:]]{2}-';
demo: https://www.db-fiddle.com/f/7mJEmCkEiYhCYK3PcEZTNE/0
Using SUBSTRING(<column>, 1, 2) should also work..
More or less like below
SELECT
<column>
, SUBSTRING(<column>, 1, 2)
FROM
<table>
WHERE
SUBSTRING(<column>, 1, 2) IN ('BA' [,<value>..])
Some things are BNF (Backus-Naur form) in the SQL code.
<..> means replace with what you need.
[, ..] means optional unlimited repeat the comma in there is part off SQL syntax
I want to use separator for group_concat() function in mysql.But I want to change the separator dynamically.I mean the separator value is coming from a table and that is different for every row.
I couldn't found any solution for that please help me.
Finally got a solution.
Let's say we have some MySQL routine. We need to GROUP_CONCAT some value with special SEPARATOR (default is ','). But SEPARATOR isn't static, it's got from another table, for ex. from some "settings" table.
DECLARE url_delimiter VARCHAR(255);
SELECT catalog_url_delimiter
INTO url_delimiter
FROM settings;
We can't use variable as SEPARATOR parameter directly:
-- doesn't work
SELECT GROUP_CONCAT(`some_table`.id SEPARATOR url_delimiter)
FROM <some query>
But we can use some dummy separator and replace it with valid as below:
SELECT
REPLACE(
GROUP_CONCAT(`some_table`.id SEPARATOR 'some-tricky-dummy-separator'),
'some-tricky-dummy-separator',
url_delimiter
)
FROM <some query>
The following query
SELECT ASSOCIATED_RISK
FROM PROJECT_ISSUES
WHERE FIND_IN_SET('98',ASSOCIATED_RISK);
returns output as
96,98
90,98
but if I use
SELECT ASSOCIATED_RISK
FROM PROJECT_ISSUES
WHERE FIND_IN_SET('96,98',ASSOCIATED_RISK);
it doesn't returns anything.In this case I would like to retrieve the first row.
96,98
Use the AND clause, like this:
SELECT ASSOCIATED_RISK
FROM PROJECT_ISSUES
WHERE FIND_IN_SET('96',ASSOCIATED_RISK)
AND FIND_IN_SET('98',ASSOCIATED_RISK)
Your query is failing because FIND_IN_SET() does not work properly if the first argument contains a comma (",") character. Reference: http://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_find-in-set. In your case, the first argument is '96,98', so it fails.
Your comment:
is there any other way I can get it in single query instead of framing multiple find_in_set and concat them
As an alternative solution, you can use locate on your ASSOCIATED_RISK value.
Example:
locate( replace( '96,98', ',', '' ), replace( ASSOCIATED_RISK, ',', '' ) )
Edit:
As per Aziz Shaikh comment, we can see that there is a possibility of true result though the search string not existing in the target string.
As an alternative solution, you can replace the search string from target string with an empty string and compare the lengths. If original string's length is grater than new replaced string, then it is a found true result.
Example:
-- this should be greater than 0 for a found true
length( ASSOCIATED_RISK ) > length( replace( ASSOCIATED_RISK, '96,98', '' ) )
This will Give result. see the difference.
SELECT ASSOCIATED_RISK FROM PROJECT_ISSUES WHERE FIND_IN_SET(ASSOCIATED_RISK,'96,98');