MySQL:选择未标记的页面?

时间:2011-02-09 23:15:57

标签: sql mysql select tagging

我有一个带有两个表的数据库,如下所示,

页面表

pg_id    title
1        a
2        b
3        c
4        d

标记表

tagged_id   pg_id
1           1
2           4

我想选择标记的页面,我尝试使用下面的查询但不起作用,

SELECT *
FROM root_pages
LEFT JOIN root_tagged ON ( root_tagged.pg_id =  root_pages.pg_id )
WHERE root_pages.pg_id !=  root_tagged.pg_id

返回零 - Showing rows 0 - 1 (2 total, Query took 0.0021 sec)

但我希望它返回

pg_id    title
    2        b
    3        c

我的查询一定是错的?
如何返回未正确标记的页面?

2 个答案:

答案 0 :(得分:2)

SELECT *
FROM root_pages
LEFT JOIN root_tagged ON root_tagged.pg_id = root_pages.pg_id
WHERE root_tagged.pg_id IS NULL

!=(或<>)运算符比较两个值,但不能用于NULL。

  • NULL = NULL返回false
  • NULL = 0返回false
  • NULL!= NULL返回false

您明白了,要检查NULL,您应该使用IS或IS NOT运算符。

答案 1 :(得分:1)

如果要标记到页面的密度大于2:1左右,那么使用NOT EXISTS将比使用LEFT JOIN + IS NULL

更快
SELECT *
FROM root_pages
WHERE NOT EXISTS (
    SELECT *
    FROM root_tagged
    WHERE root_tagged.pg_id =  root_pages.pg_id )

这是另一种选择,可以更清楚地说明你在寻找什么,不存在。

对于上面的删除线文本
问题是MySQL特定的,假设root_tagged.pg_id不可为空,则使用ANTI-JOIN实现LEFT JOIN + IS NULL,这与NOT EXISTS的策略相同,除非似乎有一些NOT EXISTS添加的开销,因此LEFT JOIN应该更快地工作。