finding a number in space separated list with REGEXP - mysql

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;

Related

Matching key words in mysql database

m trying to match key word but not exactly, something relevant, i use sql LIKE with wilcard %% something like '%mens, shoe%', will match every data with either men, mens shoe or even both, but the problem is if a user uses an apostrophe sign like this '%men\'s, shoe%', this will only match record having men's shoe or having men's with apostrophe and will not match men or mens is there a way i can make input with apostrophe sign match records without apostrophe sign thanks for any help
I'm editing my question and adding the SQL statement how it looks like
SELECT SQL_CALC_FOUND_ROWS p.product_id,p.title,p.price,p.unit_sold,p.slug,p.discount,p.free_shipping,free_return,
p.profile_img,p.store_name,p.item_number,
(
(-- Title score
if (title LIKE '%men\'s, shoe%',6,0) + if (title LIKE '%men\'s%',5,0) + if (title LIKE '%shoe%',5,0)
)+
(-- description
if (description LIKE '%men\'s, shoe%',5,0) + if (description LIKE '%men\'s%',4,0) + if (description LIKE '%shoe%',4,0)
)+
(-- item number
if (item_number = 'men\'s, shoe',4,0) + if (item_number = 'men\'s',3,0) + if (item_number = 'shoe',3,0)
)+
(-- category id
if (category_id = 'men\'s, shoe',4,0) + if (category_id = 'men\'s',3,0) + if (category_id = 'shoe',3,0)
)
) as relevance
FROM products p
WHERE p.is_active = '1'
HAVING relevance > 0
ORDER BY relevance DESC LIMIT 2,2
Your condition should look like:
someColumn LIKE '%men''s%' or someColumn LIKE '%men\''s%' or someColumn LIKE '%shoe%'
where someColumn is column name you are interested in. It will match any occurences like: men's, men\'s, etc.
Remove apostrophes before comparing:
(-- Title score
(case when replace(title, '''', '') LIKE '%mens, shoe%' then 16
when replace(title, '''', '') LIKE '%men%' then 5
when replace(title, '''', '') LIKE '%shoe%' then 5
else 0
end) +
. . .
That said, you might want to look into full text search. It might be a simpler way to accomplish what you want.

MySQL Select Column With X Words

I am trying to come up with a query that will select a row if a column has at least X words in it. For example:
SELECT * FROM TABLE IF COLUMN <has >= 3 words>
Coming up empty though. Any ideas?
3 words need at least 2 spaces. You can count the spaces in your column
select * from your_table
where length(your_column) - length(replace(your_column, ' ', '')) > 1

Mysql select all that match a number in string

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')

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.

Mysql + count all words in a Column

I have 2 columns in a table and I would like to roughly report on the total number of words.
Is it possible to run a MySQL query and find out the total number of words down a column.
It would basically be any text separated by a space or multiple space.
Doesn't need to be 100% accurate as its just a general guide.
Is this possible?
Try something like this:
SELECT COUNT(LENGTH(column) - LENGTH(REPLACE(column, ' ', '')) + 1)
FROM table
This will count the number of caracters in your column, and substracts the number of caracters in your column removing all the spaces. Hereby you know how many spaces you have in your row and hereby know how many words there are (roughly because you can also type in a double space, this wil count as two words but you say you want it roughly so this should suffice).
Count simply gives you the number of found rows. You need to use SUM instead.
SELECT SUM(LENGTH(column) - LENGTH(REPLACE(column, ' ', '')) + 1) FROM table
A less rough count:
SELECT LENGTH(column) - LENGTH(REPLACE(column, SPACE(1), ''))
FROM
( SELECT CONCAT(TRIM(column), SPACE(1)) AS column
FROM
( SELECT REPLACE(column, SPACE(2), SPACE(1)) AS column
FROM
( SELECT REPLACE(column, SPACE(3), SPACE(1)) AS column
FROM
( SELECT REPLACE(column, SPACE(5), SPACE(1)) AS column
FROM
( SELECT REPLACE(column, SPACE(9), SPACE(1)) AS column
FROM
( SELECT REPLACE(column, SPACE(17), SPACE(1)) AS column
FROM
( SELECT REPLACE(column, SPACE(33), SPACE(1)) AS column
FROM tableX
) AS x
) AS x
) AS x
) AS x
) AS x
) AS x
) AS x
I stumbled upon this post while I was looking for an answer myself and truthfully I've tested all of the answers here and the closest one was #fikre's answer. However, I have concern over data that have leading spaces and/or extra spaces between the words (trailing spaces doesn't seem to have effect to fikre's query during my testing). So, I'm looking for a way to identify any spaces in between words and remove them. While I found a few answers using advanced function (which is beyond my skill set), I did find a very simple way to do it.
tl;dr > #fikre's answer is the only one working for me but I did a minor tweak to ensure that I'll get the most accurate word count.
Query 1 -- This will return 5 "Word Count"
SELECT SUM(LENGTH(input) - LENGTH(REPLACE(input, ' ', '')) + 1) AS "Word Count" FROM
(SELECT TRIM(REPLACE(REPLACE(REPLACE(input,' ','<>'),'><',''),'<>',' ')) AS input
FROM (SELECT ' too late to the party ' AS input) i) r;
Query 2 -- This will return 13 "Word Count"
SELECT SUM(LENGTH(input) - LENGTH(REPLACE(input, ' ', '')) + 1) AS "Word Count"
FROM (SELECT ' too late to the party ' AS input) i;
-- breakdown ' too late to the party '
1 leading space= 1 word count
2 spaces after the first space from the word 'too'= 2 word count
1 space after the first space from the word 'late'= 1 word count
4 spaces after the first space from the word 'the'= 4 word count
trailing space(s) wasn't counted at all.
Total spaces > 1+2+1+4=8 + 5 word count = 13
So, basically if the data row contains even a million spaces in between (disclaimer: an assumption. I've only tested 336,896 spaces), Query 1 will still return Word count=5.
Note: The mid part REPLACE(REPLACE(REPLACE(input,' ','<>'),'><',''),'<>',' ') I took from this answer https://stackoverflow.com/a/55476224/10910692