从table1中选择*在table2中不存在条件

时间:2009-10-21 01:42:36

标签: sql mysql

我有2张桌子。一个是可以学习的东西的表。有一个JID可以描述每一行,并且每行都是唯一的。第二个表是已经学习的事物(JID)的日志,也是学习它的人的用户ID。我目前正在使用它来选择JID的所有数据,但只选择用户根据用户ID学习的数据。

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

我现在需要选择要学习的东西行,但只需要用户ID尚未学习的东西。我显然对此很新,请耐心等待。 :)我尝试使用IS NULL,但虽然看起来它有效,但它给出了重复的JID,其中一个是NULL,一个是正确的。

2 个答案:

答案 0 :(得分:19)

使用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/

答案 1 :(得分:3)

首先,您应该在现有查询中使用INNER JOIN:

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

你这样做的方式是从tablelist1获取所有行,然后在tablelog2中排除那些没有匹配的行。 INNER JOIN将为您做到这一点,并且更有效率。

其次,要为用户“X”找到用户尚未学习的所有可学习内容,请执行以下操作:

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