0

Problem:

I have a table like this :

A | B
-----------------------------------------
1 | 5,25,24,22,21,6,19,18,17,15,13,11
2 | 25,15,17,4,33,12,34,40,24,5,1,26,43,9
3 | 25,15,11,36,29

I need to select rows where my number is in column B.

try:

I use RegEx for this. I write this code :

SELECT *
FROM `table`
WHERE `B` REGEXP "([^\d]|^)MYNUMBER[^\d]

and RLIKE

([^\d]|^)MYNUMBER[^\d] : ([^\d]|^) : not number or be a first char. MYNUMBER [^\d] : not number

When MYNUMBER is 25 or 34 or any double digit number, I haven't got any problem. But when MYNUMBER is 5 or 1 or any one digit number, it's trouble.

Result example1:

input: MYNUMBER : 24

result:

A | B
-----------------------------------------
1 | 5,25,24,22,21,6,19,18,17,15,13,11

It's okay.

Result example2:

input: MYNUMBER : 5

result:

A | B
-----------------------------------------
1 | 5,25,24,22,21,6,19,18,17,15,13,11
2 | 25,15,17,4,33,12,34,40,24,5,1,26,43,9
3 | 25,15,11,36,29

Wrong answer, row 3 is wrong.

It is strange:

I tried my expression in regexr.com and it's true.

3

2 Answers 2

1

MySQL has a function for this: FIND_IN_SET()

http://dev.mysql.com/doc/refman/5.5/en/string-functions.html#function_find-in-set

In the long run you may want to think about normalizing this into two tables ...

Sign up to request clarification or add additional context in comments.

Comments

1

The number has to be a consecutive set of digits that is either surrounded by commas, or is the first or last thing in the string. You could add to this to tolerate optional whitespace if desired.

SELECT *
FROM `table`
WHERE `B` REGEXP "^25," OR `B` REGEXP ",25," OR `B` REGEXP ",25$"

5 Comments

@spencer7593 whoops yes, logic was wrong and had false-positive matches. And I am not sure why this answer would be used rather than FIND_IN_SET except as an academic exercise, but hey, maybe as a REGEXP learning exercise.
This a workable approach. Sometimes the MySQL optimizer doesn't handle OR conditions that well. Consider the equivalent: CONCAT(',',B,',') REGEXP ',25,'.
I'd have to test to see which was faster against various engines. I find the OR version more intuitively readable and checkable for correctness, but the CONCAT with a single REGEXP is elegant.
,,, in this particular case, either way, MySQL can't make use of a range scan operation. It's going to have to evaluate the predicate for every flipping row in the table. So, we're basically weighing the CPU/memory cost of evaluating three regular expressions (in the worst case of no matches found), against the cost of allocating/copying a string, and doing a single regular expression evaluation. My bet is the difference is negligible. (I don't think the FIND_IN_SET is going to give much different performance either.)
Agreed. Which is why normalizing into two tables is a far, far better answer than any of these!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.