1

I have a list of numbers in some fields in a table, for example something like this:

2033,1869,1914,1913,19120,1911,1910,1909,1908,1907,1866,1921,1922,1923

Now, I'm trying to do a query to check if a number is found in the row, however, I can't use LIKE as then it may return false positives as if I did a search for 1912 in the above field I would get a result returned because of the number 19120, obviously we don't want that - we can't append or prepend a comma as the start/end numbers don't have them.

So, onto using REGEXP I go... I tried this, but it doesn't work (it returns a result):

SELECT * FROM cat_listing WHERE cats REGEXP '[^0-9]*1912[^0-9]*';

I imagine why it still finds something is because of the * quantifier; it found [^0-9] 0 times AFTER 1912 so it considers it a match.

I'm not sure how to modify it to do what I want.

4
  • 1
    How about not storing comma-separated list in a field? This is what parent-child relationship in a database is for. Commented Jun 28, 2015 at 18:06
  • 1
    Did you try with word boundaries: SELECT * FROM cat_listing WHERE cats REGEXP '[[:<:]]1912[[:>:]]';? Commented Jun 28, 2015 at 18:07
  • @AleksG I'm aware of that, but for this situation this is the best method and a parent child relationship isn't needed. Commented Jun 28, 2015 at 18:10
  • @stribizhev That seems to work great. Feel free to post as an answer. Commented Jun 28, 2015 at 18:12

3 Answers 3

2

In your case, it seems word boundaries are necessary:

SELECT * FROM cat_listing WHERE cats REGEXP '[[:<:]]1912[[:>:]]';

[[:<:]] is the beginning of a word and [[:>:]] is the end. See reference:

[[:<:]], [[:>:]]

These markers stand for word boundaries. They match the beginning and end of >words, respectively. A word is a sequence of word characters that is not >preceded by or followed by word characters. A word character is an alphanumeric >character in the alnum class or an underscore (_).

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

Comments

2

You have another option called find_in_set()

SELECT * FROM cat_listing WHERE find_in_set('1912', cats) <> 0;

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.

2 Comments

This is by far the best answer. I don't know why it was not chosen. But then again, someone who stores lists in comma-separated fields is probably a bit weak on SQL and data representation.
@GordonLinoff It wasn't chosen because it wasn't available as an answer when I selected the other answer, simple as that. Additionally, you have no idea how I am using this data so don't make assumptions that I should be storing it in another manner.
1

No need to use a regex just because the column value has no comma at either end:

SELECT
  cats
FROM cat_listing
WHERE INSTR(CONCAT(',', cats, ','), ',1912,')
;

See it in action: SQL Fiddle.
Please comment if adjustment / further detail is required.

Comments

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.