Mysql select all that match a number in string - mysql

Assume my table column contains the following 2 string rows:
1, 5, 2, 31, 12, 1212, 111
21, 25, 32, 43, 112, 212, 311
I need a query to select a row that contains number 1 and contains number 2
My Query is:
SELECT *
FROM MyTable
WHERE My_String LIKE '%1%' AND My_String LIKE '%2%'
now this returns both of the rows when i want it to return only the first row.
It selects second row because numbers 21, 25, 32, 112, 212, 311 also contain number 1 and 2.
My question is how do i select all those rows where numbers 1 and 2 are contained in a string but not in 2-3 digit numbers. I want it to match strictly to those 1 and 2

http://www.sqlfiddle.com/#!2/b082d/5
select * from testtable
where instr(concat(', ', longstring, ', '), ', 2,') >0;
select * from testtable
where instr(concat(', ', longstring, ', '), ', 1,') >0
and instr(concat(', ', longstring, ', '), ', 2,') >0;

You can use a regular expression. [[:<:]] is a beginning word boundary and [[:>:]] is end word boundary.
SELECT * FROM MyTable
WHERE My_String RLIKE '[[:<:]]1[[:>:]]'
AND My_String RLIKE '[[:<:]]2[[:>:]]'

You have few options:
1- As mentioned in a comment on the main post, change the structure and don't store concatenated strings
2- write a function that splits the string and checks if the numbers 1 and 2 appear in the tokens after splitting.
3- write "where" clause that captures every possibility of appearance for a string:
a string can appear in the beginning, middle, end of the list or be the only element in the list. the last one, is not important since you require 1 and 2 to appear in a row, and therefore a list String containing a single element should be eliminated. so:
select *
from MyTable
where (My_String like '1,%' or My_String like '%, 1,%' or My_String like '%, 1')
and (My_String like '2,%' or My_String like '%, 2,%' or My_String like '%, 2')

Related

MySQL How LIKE 1 digit

I have this records:
Number
1, 2
1, 24
How to select only 2 by LIKE not 2 and 24
SELECT * FROM test WHERE number LIKE '%2%'
1, 2 // need only this record
1, 24
You should avoiding storing unnormalized CSV data like this. That being said, if you must proceed, here is one way:
SELECT *
FROM test
WHERE CONCAT(' ', number, ' ') LIKE '% 2 %';
find_in_set almost does what you want, but you'll have to remove the spaces in order to use it:
SELECT *
FROM test
WHERE FIND_IN_SET('2', REPLACE(number, ' ', '')) > 0
You can do it as follows :
SELECT `number`
FROM `test`
WHERE TRIM(SUBSTRING_INDEX(`number`, ',', -1)) = 2 or TRIM(SUBSTRING_INDEX(`number`, ',', 1)) = 2;
SUBSTRING_INDEX to split number, and TRIM to remove any space, then we search in to parts of the number.

mysql SUBSTRING() and LOCATE()

I am using mysql's SUBSTRING() function and LOCATE() to capture "n" characters before and after some string.
For example, using the string "apple". When I query it works fine except if the string "apple" is towards the beginning of the string since 10 characters before may be non-existent:
http://sqlfiddle.com/#!9/f41f8d/5
CREATE TABLE demo (name varchar(1000));
INSERT INTO demo (name) VALUES
("An apple a day keeps the doctor away"),
("A doctor a day keeps the apple away from the doctor");
SELECT SUBSTRING(
`name`,
LOCATE("apple",`name`) - 10, /* from 10 characters before 'string'*/
(25) /* to 10 characters after the 5 strlen string (so 10 + 5 + 10) */
)
FROM demo
WHERE name like '%apple%'
Results
| r away |
| keeps the apple away from |
The second results is as expected, but the first - I would like it to start at the beginning of the string until 10 characters after "apple".
What's wrong with my query or how can I fix it? I'm also queries millions of rows so I assume a sub-query to check if it's position is less than "string"'s length isn't performant?
Try with this:
SELECT SUBSTRING(
`name`,
GREATEST(LOCATE("apple",`name`) - 10, 1), /* from 10 characters before 'string'*/
LEAST(25, LENGTH(name) - GREATEST(LOCATE("apple",`name`) - 10, 1)) /* to 10 characters after the 5 strlen string (so 10 + 5 + 10) */
)
FROM demo
WHERE name like '%apple%'
Something like this:
SELECT SUBSTRING(name,
GREATEST(1, LOCATE('apple', name) - 10),
15 + LEAST(LOCATE('apple', name), 10)
)
FROM demo
WHERE name like '%apple%'

finding a number in space separated list with REGEXP

I am writing a SQL query to select row, where a field with space separated numbers contains a single number, in this example the 1.
Example fields:
"1 2 3 4 5 11 12 21" - match, contains number one
"2 3 4 6 11 101" - no match, does not contain number one
The best query so far is:
$sql = "SELECT * from " . $table . " WHERE brands REGEXP '[/^1$/]' ORDER BY name ASC;";
Problem is that this REGEXP also finds 11 a match
I read many suggestions on other post, for instance [\d]{1}, but the result always is the same.
Is it possible to accomplish what I want, and how?
You don't need regex: You can use LIKE if you add a space to the front and back of the column:
SELECT * from $table
WHERE CONCAT(' ', brands, ' ') LIKE '% 1 %'
ORDER BY name
Try:
WHERE brands REGEXP '[[:<:]]1[[:>:]]'
[[:<:]] and [[:>:]] match word boundaries before and after a word.
Why not FIND_IN_SET() + REPLACE() ?
SELECT
*
FROM
`table`
WHERE
FIND_IN_SET(1, REPLACE(`brands`, ' ', ','))
ORDER BY
`name` ASC;

How to select rows with a certain number in one of its columns?

In one of the columns of my table (say it's called foo), it stores a set of 10 numbers, e.g:
1, 5, 8, 3, 4, 6, 9, 7, 12, 15
I wish to select all rows of my table which have the number 6 in the foo column.
Well, you might say, this sounds simple enough, just do a string search on the column. But the problem is, then you would also select rows with 16 in them, as 16 contains a 6.
I also thought about searching for , 6, instead, but I realized if 6 was on the very end or front of the string, it won't match.
How can I overcome this problem?
use MySQL built-in function called FIND_IN_SET.
SELECT *
FROM tablename
WHERE FIND_IN_SET('6', REPLACE(foo,' ','')) > 0
SQLFiddle Demo
FIND_IN_SET()
From Docs:
Returns a value in the range of 1 to N if the string str is in the
string list strlist consisting of N substrings. A string list is a
string composed of substrings separated by “,” characters. If the
first argument is a constant string and the second is a column of type
SET, the FIND_IN_SET() function is optimized to use bit arithmetic.
Returns 0 if str is not in strlist or if strlist is the empty string.
Returns NULL if either argument is NULL. This function does not work
properly if the first argument contains a comma (“,”) character.
You can append a ', ' to the beginning and end of foo and search:
SELECT *
FROM bar
WHERE ', ' + foo + ', ' LIKE '%, 6, %'

count substring_index

i need to know how substring_index can only return all rows that match exactly the number of delimiters. In this case the .
For example this query:
SELECT
SUBSTRING_INDEX(ABC, '.', 4)
FROM xxx
only should output when the row is exactly something like this (with 4 words):
aaa.bbb.ccc.ddd
The problem is that: this row is also showed .
aaa.bbb
This will return anything where ABC has 3 . delimiters.
select *
from xxx
where char_length(replace(ABC, '.', '')) + 3 = char_length(ABC)
You would need to multiply 3 by your delimiter length if you had a multi-character string for your delimiter.