manipulate string in where clause - mysql

I have a variable list_name containing list of names separated by ':'
list_name=(rahul:john:steve) => list_name is of type 'string'
The list contains 1000s of names
Can't change the list_name because we get it from other department/company
want to write a query do to the purpose as shown below, but for that string manipualation would be required i.e. extracting the names from list_names based on the separator ':'
select roll_no from students
where names is rahul or john or steve (problem part)
suggest to use some string manipulation technique in sql to extract the names from the string
PS: I am using proprietary sql and looping is not supported

You can do this in standard'ish SQL using:
select roll_no
from students
where concat(':', list_name, ':') like concat('%:', names, ':%')
In some databases, the where might be written as:
where ':'+ list_name+':' like '%:'+names+':%'
or
where ':'|| list_name||':' like '%:'||names||':%'

Related

search values using like clause on alias column

I have table which contain comma separated string I want to perform like query on 'name' column but 'name' is comma separated so it will not retrieve data easily so I am using replace to eliminate comma and than perform like query on alias column ,but It is not working.is there any way to perform like query on comma separated string
Table:
id name
i school,education
mysql query :
SELECT id,name, lower((REPLACE(name, ',', ''))) as test FROM `list`
where test like '%education%'
You should seriously avoid storing CSV data into single table columns as you are currently doing. That being said, here is one possible workaround:
SELECT id, name
FROM list
WHERE CONCAT(',', LOWER(name), ',') LIKE '%,education,%';
The idea behind the above trick is to build a CSV name string looking something like:
,A,B,C,D,
That is, every single name value is always surrounded by comma boundaries on both sides. Then, we only need to check that ,somename, be present in this CSV string.

How to check if a string in one field exist in every element of a comma separated field

I have a table which contains two fields. The first is name of type string. The second contains one or more strings separated by comma (but it can contain a single string with no commas at all)
I want to construct a query to know if the string in the name field does not exist in every comma separated strings in the names field.
Example 1:
---------------------------------------------------------
name names
---------------------------------------------------------
myname xmyname,myname,mynamey
All the comma separated strings contain the word myname. So the query shoudl not return this row.
But, Example 2:
---------------------------------------------------------
name names
---------------------------------------------------------
myname x,myname,mynamey
Should be returned. Because x does not contain myname.
The condition is that, if the string in the field name does not exists in each of the comma separated strings in the names field, then return the row.
This is not correct as this query will not return true in example 2 (which contains x which does not contain myname).
IMPORTANT NOTE:
1) There is not limit of how many commas there. It can be 0 commas or more. How to deal with this?
2) The strings are variables. It is not always the case that the string is myname. Each row contains a different string in the name field.
Try this regular expression:
where not concat(names, ',') regexp replace('^([^,]*{n}[^,]*,)*$', '{n}', name)
db-fiddle demo
How to read the pattern:
The inner pattern [^,]*{n}[^,]*, means
Any non comma character [^,] repeated any number of times (* means no times or multiple times).
followed by the value of the column name ({n} is a placeholder and will be replaced with the actual value using the replace() function)
followed by any non comma character [^,] repeated any number of times
followed by a comma
The outer pattern ^({inner_pattern})*$ means
Start of the string (^)
followed by the inner pattern repeated any number of times
followed by end of string ($)
To make this work, a comma is appended to the names column (concat(names, ',')), so that every element in the string ends with a comma.
The pattern will ensure, that any element in the comma separated string contains the value of the name column. Since you want the opposite result, we use where not ...
Assuming "myname" does not appear twice between two commas, you can count the commas and "myname"s:
where (length(names) - length(replace(names, ','))) >=
length(names) - length(replace(names, 'myname', '12345'))
This answer started off giving an incorrect REGEXP solution. But the best thing to do here would be to fix your data model, such that each name in the names column is actually on a separate row:
name | names
myname | xmyname
myname | myname
myname | mynamey
somename | x
somename | myname
somename | mynamey
Now we can do a simple aggregation query to answer your question:
SELECT name
FROM yourTable
GROUP BY name
HAVING COUNT(CASE WHEN names NOT LIKE CONCAT('%', name, '%') THEN 1 END) > 0;
Demo
You can approach this using the following SQL query
SELECT
name, names
FROM
`tablename`
WHERE
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1)
=
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
)/ LENGTH(name)
);
Explanation:-
This Will give you how many words are separated with ,
(LENGTH(names) - LENGTH(REPLACE(names, ',', '')) + 1) -
Following is matching the name in each row and returning how many times it found
ROUND (
(
LENGTH(names)
- LENGTH( REPLACE ( names, name, "") )
) / LENGTH(name)
)
DEMO

If value is present in stored text string

I have a table, one of the columns contains a text values, some of which are comma separated string, like this:
Downtown, Market District, Warehouse District
I need to modify my query to see is a given value matches this column. I decided that using IN() is the best choice.
SELECT *
FROM t1
WHERE myValue IN (t1.nighborhood)
I am getting spotty results - sometimes I return records and sometimes not. If there's a value in t1.nighborhood that matches myValue, I do get data.
I checked and there are no MySQL errors. What am I missing?
You can use FIND_IN_SET() to search a comma-delimited list:
SELECT *
FROM t1
WHERE FIND_IN_SET(myValue, REPLACE(t1.nighborhood, ', ', ','));
The REPLACE() is necessary to remove the extra spaces.
Another solution is to use regex to match your search value surrounded by commas if necessary:
SELECT *
FROM t1
WHERE t1.nighborhood REGEXP CONCAT('(^|, )', myValue, '(, |$)');
In general, it's bad design to store distinct values in a single column. The data should be normalized into a related table with a foreign key.

random column name generated by azure sql

I'm noticing when I make any select statement with json data outputs a column name with random title e.g.
select 'john' as firstname, 'smith' lastname for json path
if I run this in sql management studio (text results) I'll get
JSON_F52E2B61-18A1-11d1-B105-00805F49916B
-------------------------------------------- [{"firstname":"john","lastname":"smith"}]
(1 row(s) affected)
How to change the column name of the generated json data. I've tried using the root option but couldn't override the column title.
This is the same as using XML.
you cannot set the column name
for my opinion since you will always get single row and single column (which means that this is only one value)
the column name have no meaning. but maybe you have different scenario that i am not aware of.
anyway, if you want to workaround it you can use this query
select (select 'john' as firstname, 'smith' lastname for json path) as MyColumn

mySQL: Trouble with select query containing | symbol (LIKE and/or REGEXP)

My current query looks like this:
$query = "SELECT * FROM t WHERE (data LIKE '$findme') OR (data LIKE '%$findme|%') OR (data LIKE '%|$findme%')";
The data in this column contains items that are delimited by pipe symbols ("|") and I need the query to find all records that contain any occurrences of an item in this field. Additionally, if there's only one item in this column, there will not be a "|" symbol present.
EXAMPLE:
$findme = "12";
QUERY SHOULD MATCH:
13|23|12
12
12|23
3|12|42
QUERY SHOULD NOT MATCH:
123|32
34|123
I'm not sure if using REGEXP would make this easier, but if so, any solution is welcome. Thanks!
SQLFiddle Example:
http://sqlfiddle.com/#!3/32afd/5
Using a combination of REPLACE() and FIND_IN_SET(), you can replace the | with commas, and locate your value $findme in the pipe-delimited set:
SELECT *
FROM table
/* Replace | with , and search in the set */
WHERE FIND_IN_SET('$find_me', REPLACE(data, '|', ',')) > 0
Note that this only works if the delimited values in data do not contain commas.
In the long run, the appropriate solution to this is to separate out the delimited column data into another properly normalized one to many table.