MySQL LIKE оператор для номеров, разделенных запятыми - PullRequest
1 голос
/ 10 апреля 2020

Это не дубликат, так как я попробовал все решения, которые мне удалось найти здесь. Я даже не знаю, как включить мой вопрос в заголовок.

У меня в столбце числовые значения c:

+-----------+
| tags      |
+-----------+
| 1,14      |
| 2,3       |
| 2,4       |
| 1,14      |
| 2,3,4     |
| 1         |
| 9         |
| 1,2,15,16 |
| 1,3,17    |
| 1,18      |
| 2,3,4     |
| 20,21     |
+-----------+

И я хочу выбрать пост, например, tag = 1.

Если я буду вести себя так

"SELECT * FROM articles WHERE tags LIKE '%1%'";

MySQL вернет все помеченные сообщения: 14, 15, 16, 21 ... любое другое число, содержащее «1»;

Я пробовал множество утверждений, которые ничего мне не дали, таких как:

$result = $this->db->query("SELECT * FROM articles WHERE CONCAT(',', tags, ',') LIKE ? ORDER BY date_pub DESC LIMIT 4", "%,$tag_id,%")->fetchAll();

и т. Д .;

К сожалению, каждый раз, когда я сталкиваюсь с одним и тем же результатом. MySQL возвращает все числа, которые содержат «1».

Другими словами, 1, 13, 127494849040450, 3900000000000001, везде MySQL видит «1», он возвращает статью.

Но моя цель - взять уникальный номер из строки VARCHAR, разделенной запятыми, и вернуть статью, которая имеет такой тег цифра c.

Буду признателен, если кто-нибудь может помочь мне с этим вопросом.

Ответы [ 4 ]

2 голосов
/ 10 апреля 2020

Для этой проблемы есть функция FIND_IN_SET():

SELECT * 
FROM articles 
WHERE FIND_IN_SET('1', tags)

Если вы хотите использовать LIKE:

SELECT *
FROM articles
WHERE CONCAT(',', tags, ',') LIKE '%,1,%'

или лучше использовать CONCAT() для параметра '1' тоже:

SELECT *
FROM articles
WHERE CONCAT(',', tags, ',') LIKE CONCAT('%,', '1', ',%')
1 голос
/ 10 апреля 2020

Способ устранения проблемы (вместо устранения только симптома и продолжения причины root) заключается в нормализации данных, чтобы вы не использовали значения, разделенные запятыми. Это упростит данные, улучшит производительность запросов и предотвратит проблемы, точно такие же, как у вас.

Сказав это, вы, возможно, сможете обойти ваш обходной путь примерно так:

WHERE `tags` = '1' OR `tags` LIKE '1,%' OR `tags` LIKE '%,1,%' OR `tags` LIKE '%,1'

Это предполагает, что вы не можете гарантировать, что теги всегда будут в отсортированном порядке. В конце концов, это всего лишь строка, а не сортируемый список числовых значений c. Если вы можете смело предположить, что они всегда будут в порядке, это тоже поможет:

WHERE `tags` = '1' OR `tags` LIKE `1,%`
0 голосов
/ 10 апреля 2020

Здесь можно использовать регулярное выражение типа aka RLIKE

SELECT * FROM articles WHERE tags RLIKE '(^|,)nn(,|$)'; -- where nn the need number 

Начало совпадения регулярного выражения - строка или запятая (^ |,), затем число, которое нам нужно, затем следует кома или конец строки (, | $)

0 голосов
/ 10 апреля 2020

WHERE tags = '1' ИЛИ ​​теги, такие как '1,%'

  • Предполагается, что теги расположены в порядке нумерации c, а 1 - первый, когда присутствует. В противном случае потребуются дополнительные пункты.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...