Mysql запрос, чтобы выбрать все, кроме
У меня есть две таблицы mysql.
первый называется "выбранным" и состоит из полей id, user_id и widget_id.
другой называется "виджеты" и включает в себя несколько вещей, включая widget_id.
я создал фильтр, чтобы пользователь мог либо отображать выбранные им виджеты, либо виджеты, которые он/она не выбрал. для тех, которые он выбрал, я использую это:
SELECT *
FROM widgets, chosen
WHERE chosen.user_id = $user_id
AND chosen.widget_id = widgets.widget_id
Однако я не могу понять, как отображать те, которые он/она не выбрал. это не работает (отображает все):
SELECT *
FROM widgets, chosen
WHERE !( chosen.user_id = $user_id
AND chosen.widget_id = widgets.widget_id)
как это сделать?
Ответы
Ответ 1
Использование NOT IN:
SELECT w.*
FROM WIDGET w
WHERE w.widget_id NOT IN (SELECT c.widget
FROM CHOSEN c
WHERE c.user_id = $user_id)
Использование NOT EXISTS:
SELECT w.*
FROM WIDGET w
WHERE NOT EXISTS (SELECT NULL
FROM CHOSEN c
WHERE c.widget_id = w.widget_id
AND c.user_id = $user_id)
LEFT JOIN/IS NULL:
SELECT w.*
FROM WIDGET w
LEFT JOIN CHOSEN c ON c.widget_id = w.widget
AND c.user_id = $user_id
WHERE w.widget IS NULL
Производительность:
Если сравниваемые столбцы (widget_id в любой таблице) не могут быть нулевыми, LEFT JOIN/IS NULL лучше всего работает в MySQL. Если столбцы имеют значение NULL (значение может быть NULL), NOT IN или NOT EXISTS работают лучше.
Ответ 2
Логическая логика: (ab)'
совпадает с a' + b'
SELECT *
FROM widgets, chosen
WHERE chosen.user_id <> $user_id
OR chosen.widget_id <> widgets.widget_id
Ответ 3
В принципе, вы хотите выбрать все строки из widgets
, у которых нет соответствующей строки в chosen
для данного $user_id
. Вы можете выполнить это с помощью LEFT OUTER JOIN
для поиска строк, которые не совпадают в таблице chosen
. Что-то вроде этого:
SELECT w.* FROM widgets as w
LEFT OUTER JOIN chosen as c on c.widget_id=w.widget_id AND c.user_id=$user_id
WHERE c.id IS NULL;
BTW: Я рекомендую использовать синтаксис нового синтаксиса по синтаксису объединения таблиц с разделителями-запятыми. Это легче читать и понимать, особенно когда речь идет о внешних объединениях.