Выберите * из таблицы1, которая не существует в таблице2 с условным

У меня есть 2 таблицы. Одна из них - таблица с вещами, которые можно узнать. Существует JID, который описывает каждый тип строки и уникален для каждой строки. Вторая таблица - это журнал событий, которые были изучены (JID), а также идентификатор пользователя для человека, который его изучил. В настоящее время я использую это, чтобы выбрать все данные для JID, но только те, которые пользователь узнал на основе userid.

SELECT * 
FROM tablelist1
LEFT JOIN tablelog2 ON (tablelist1.JID = tablelog2.JID) 
                       AND tablelog2.UID = 'php var'
WHERE tablelog2.JID IS NOT NULL

Теперь мне нужно выбрать строки вещей, чтобы узнать, но только те вещи, которые ИД не удалось узнать. Я, очевидно, очень новичок в этом, медведь со мной.:) Я пробовал использовать IS NULL, но, похоже, он работает, он дает дубликат JID, который является NULL, причем один из них правильный.

Ответ 1

Использование LEFT JOIN/IS NULL:

   SELECT t.*
     FROM TABLE_LIST t
LEFT JOIN TABLE_LOG tl ON tl.jid = t.jid
    WHERE tl.jid IS NULL

Использование NOT IN:

SELECT t.*
  FROM TABLE_LIST t
 WHERE t.jid NOT IN (SELECT tl.jid
                       FROM TABLE_LOG tl
                   GROUP BY tl.jid)

Использование NOT EXISTS:

SELECT t.*
  FROM TABLE_LIST t
 WHERE NOT EXISTS(SELECT NULL
                    FROM TABLE_LOG tl
                   WHERE tl.jid = t.jid)

FYI
LEFT JOIN/IS NULL и NOT IN эквивалентны в MySQL - они будут выполнять то же самое, в то время как NOT EXISTS работает медленнее/менее эффективно. Для получения дополнительной информации: http://explainextended.com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/

Ответ 2

Во-первых, вы должны использовать INNER JOIN для существующего запроса:

SELECT * FROM tablelist1
    INNER JOIN tablelog2 ON (tablelist1.JID = tablelog2.JID) 
    WHERE tablelog2.UID = 'php var'

Как вы это делаете, вы получаете все строки из таблицы list1, а затем получаете дополнительные проблемы, чтобы исключить те, которые не имеют соответствия в tablelog2. INNER JOIN сделает это для вас и более эффективно.

Во-вторых, чтобы найти для пользователя "X" все обучаемые вещи, которые пользователь не изучил, выполните:

SELECT * FROM tablelist1 
    WHERE NOT EXISTS (SELECT JID FROM tablelog2 WHERE UID = 'X')