1
I have a table in the database with the following structure:
+---------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| numeros | text | YES | | NULL | |
+---------+---------+------+-----+---------+----------------+
In it, I have the following values:
+----+-------------------------------------+
| id | numeros |
+----+-------------------------------------+
| 1 | 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 2 | 1,3,5,9,11,13,15 |
| 3 | 2,4,6,8,10,12 |
| 4 | 1 |
| 5 | 15 |
+----+-------------------------------------+
numeros is a column containing comma separated values (CSV).
How can I select lines containing any number from that set?
For example, select all rows in which the column numeros contain the value 1.
I tried to make cases like:
mysql> SELECT * FROM `tabela` WHERE `numeros` LIKE '%1%';
+----+-------------------------------------+
| id | numeros |
+----+-------------------------------------+
| 1 | 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 2 | 1,3,5,9,11,13,15 |
| 3 | 2,4,6,8,10,12 |
| 4 | 1 |
| 5 | 15 |
+----+-------------------------------------+
In this case he ends up selecting everyone who has the number 1, literally. As is the case with lines 3 and 5.
mysql> SELECT * FROM `tabela` WHERE `numeros` LIKE '%1,%';
+----+-------------------------------------+
| id | numeros |
+----+-------------------------------------+
| 1 | 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 |
| 2 | 1,3,5,9,11,13,15 |
+----+-------------------------------------+
Already in this, it seems to work well, but the line 4 is not selected.
Besides, I’ve been trying to avoid the LIKE, since this number will be typed by the user. And as always say, never trust the user input, even more so for a case like the LIKE.
Numbers are always saved in an orderly fashion?
– Giuliana Bezerra
No, and number one was just an example, it would have to work for any other number
– dgadelha
Yes, but the list of numbers would always be sorted?
– Giuliana Bezerra
No, since the server accepts any type of CSV that contains numbers then it would work with
4,1,3,5, for example– dgadelha
Ahh, so it’s more complicated :)
– Giuliana Bezerra
Yeah, I broke my head a lot with that right there haha
– dgadelha
As mysql, the options are more restricted. Using like you would need to test all cases that are: Single element in the list, element starting the list, element in the middle of 2 elements of the list, and element ending the list. Did you think to do it this way? I don’t suggest as an answer because it wouldn’t be very elegant, but it would solve.
– Giuliana Bezerra
1 change the model , normalize this table 2 change the model , normalize this table 3 not being possible to apply an "unpivot" in this column , mysql has not ready that I know but there are contour solutions --- you should rethink a model when answers that should be simple become complicated.
– Motta
What is the/the right model/normalisation/a to do this?
– dgadelha
Putting in 3FN you would no longer have a multivariate column. This column would be a new table with a foreign key for the table that originated it. Then it would be easy to adjust the query using the 2 tables.
– Giuliana Bezerra
The only alternative would be to create another table? I’m thinking about the agility of the query. Imagine that I would have several users. These numbers would be like features they have. I wanted to query all users who have a certain resource. Wouldn’t it be too heavy when I join many users and many features? Not only heavy in order size, but heavy in disk space.
– dgadelha
Try LIKE '%,@num,%' being @in a user input parameter.
– Victor Freitas
Victor, in his case, ended up not taking any table row as specified above.
– dgadelha
So try like '%,'||@num|',%' I tested it here and it looks like it worked.
– Victor Freitas
This one didn’t work out with me no
– dgadelha
Not changing the model implies a complex sql to do a simple thing
– Motta