Задать вопрос
@Snewer

Проблема с sql запросом (NOT IN)

Здравствуйте!

Почему не работает следующий запрос:
SELECT MAX(`ex4-id`) 
FROM `ex4`
WHERE `ex2-id` = 104
AND `ex4-id` NOT IN (SELECT `usr-ex4-ids` FROM `users` WHERE `usr-id` = 51)

Подзапрос
SELECT `usr-ex4-ids` FROM `users` WHERE `usr-id` = 51

возвращает последовательность ИДов (17,18,19,20)

Следующий запрос отрабатывает на УРА:
SELECT MAX(`ex4-id`) 
FROM `ex4`
WHERE `ex2-id` = 104
AND `ex4-id` NOT IN (17,18,19,20)


В чем проблема? Спасибо.
  • Вопрос задан
  • 2809 просмотров
Подписаться 1 Оценить 1 комментарий
Решения вопроса 2
nowm
@nowm
Если у вас `usr-ex4-ids` — это строка, в которой через запятую перечислены идентификаторы, то неработающий запрос, после выполнения подзапроса, выглядит так:

# . . .
AND `ex4-id` NOT IN ("17,18,19,20")

То есть, как вы видите, в скобках получается не несколько элементов, разделённых запятыми, а один элемент — строка, внутри которой есть цифры и запятые.

Есть несколько вариантов.

1. Можно сделать дополнительную таблицу, в которую записывается соответствие ex4-id и user-id.

CREATE TABLE `usr-ex4-ids` (
 `ex4-id` int(11) NOT NULL,
 `usr-id` int(11) NOT NULL,
 PRIMARY KEY (`ex4-id`,`usr-id`)
)


Далее эта таблица заполняется соответствующими значениями (один ex4-id на строку, а не перечисление ex4-id в одной строке через запятую). Итоговый запрос, который сейчас у вас не работает, будет выглядеть так:

# . . .
AND `ex4-id` NOT IN (SELECT `ex4-id` FROM `usr-ex4-ids` WHERE `usr-id` = 51)


2. Можно попытаться сделать конвертацию строки в массив. Встроенных функций в MySQL для таких задач нет. Советую посмотреть комментарии пользователей к списку строковых функций MySQL — там есть несколько интересных решений (комментарии, как и положено комментариям, находятся в конце страницы).

Но вообще, я советую первый вариант, так как он логичнее, проще и быстрее. По второму варианту вам скорее всего придётся собственные функции MySQL писать. И они будут работать гораздо медленнее, чем вариант с нормализацией БД.
Ответ написан
Комментировать
SilentSokolov
@SilentSokolov
Используйте NOT EXISTS
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы