MySQL:选择未标记的页面?

发布于 2024-10-16 20:26:22 字数 627 浏览 1 评论 0原文

我有一个数据库,其中有两个表,如下所示,

页表

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

它返回零 - 显示行 0 - 1(总共 2 行,查询花费了 0.0021 秒)

但我希望它返回

pg_id    title
    2        b
    3        c

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

I have a db with two tables like these below,

page table

pg_id    title
1        a
2        b
3        c
4        d

tagged table

tagged_id   pg_id
1           1
2           4

I want to select the pages which are tagged, I tried with this query below but doesn't work,

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

It returns zero - Showing rows 0 - 1 (2 total, Query took 0.0021 sec)

But I want it to return

pg_id    title
    2        b
    3        c

My query must have been wrong?
How can I return the pages which are not tagged correctly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

℡寂寞咖啡 2024-10-23 20:26:22
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 运算符。

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

The != (or <>) operator compare two values, but cannot be used for NULL.

  • NULL = NULL returns false
  • NULL = 0 returns false
  • NULL != NULL returns false

You get the point, to check for NULL you should use the IS or IS NOT operator.

乜一 2024-10-23 20:26:22

如果您标记页面的密度大于 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不可为空,LEFT JOIN + IS NULL是使用ANTI-JOIN实现的,这与NOT EXISTS的策略相同,除了NOT EXISTS似乎增加了一些开销,所以LEFT JOIN应该工作得更快。

If your density to tag to pages is more than 2:1 or so, then using NOT EXISTS will be faster than using LEFT JOIN + IS NULL

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

It is an alternative that more clearly states what you are looking for, a non-existence.

For the strikeout text above:
The question is MySQL specific, and assuming root_tagged.pg_id is not nullable, LEFT JOIN + IS NULL is implemented using ANTI-JOIN which is the same strategy as NOT EXISTS, except there seems to be some overhead added by NOT EXISTS, so LEFT JOIN is supposed to work faster.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文