mysql查询选择除了之外的所有内容

时间:2010-12-10 04:44:11

标签: sql mysql

我有两个mysql表。

第一个名为“selected”,由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)

我该怎么做?

3 个答案:

答案 0 :(得分:19)

使用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为空:

   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

性能:

如果是columns compared (widget_id in either table) are not nullable, LEFT JOIN/IS NULL performs the best on MySQL。如果是columns are nullable (the value could be NULL), NOT IN or NOT EXISTS perform better

答案 1 :(得分:1)

布尔逻辑:(ab)'a' + b'

相同
SELECT * 
  FROM widgets, chosen 
 WHERE chosen.user_id <> $user_id 
         OR chosen.widget_id <> widgets.widget_id

答案 2 :(得分:0)

基本上,您希望从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; 表中不匹配的行来完成此操作。像这样:

{{1}}

顺便说一句:我建议使用较新的连接语法而不是逗号分隔的表连接语法。它更易于阅读和理解,尤其是涉及外连接时。