【问题标题】:Does the result differs when writing condition in JOIN over in WHERE clause?在 WHERE 子句中的 JOIN 中写入条件时结果是否不同?
【发布时间】:2020-11-10 15:48:44
【问题描述】:

wherejoin 中使用条件的结果是否存在差异?在我的实际查询中,我可以将AND "noteReads"."id" IS NULL 放入wherejoin。这有关系吗?

在 where 子句中带有 AND "noteReads"."userId" = 1 的第一个版本:

SELECT count(distinct("notes"."id")) FROM "notes"
LEFT OUTER JOIN "noteReads" ON "notes"."id" = "noteReads"."noteId" 
  AND "noteReads"."userId" = 1 
WHERE (
  "notes"."archivedAt" IS NULL
  AND "notes"."authorId" != 1
  AND "noteReads".id IS NULL
);

在连接子句中带有AND "noteReads"."userId" = 1 的第二个版本:

SELECT count(distinct("notes"."id")) FROM "notes"
LEFT OUTER JOIN "noteReads" ON "notes"."id" = "noteReads"."noteId" 
  AND "noteReads"."userId" = 1
  AND "noteReads"."id" IS NULL
WHERE (
  "notes"."archivedAt" IS NULL
  AND "notes"."authorId" != 1
);

【问题讨论】:

  • distinct 不是函数,这里是 。直接写count(distinct "notes"."id"),让代码更清晰。
  • 顺便说一句,第一个查询是一个反连接(您可以计算 不存在用户 1 读取的便笺的便笺)。更好地使用NOT EXISTSNOT IN 以获得更易读的查询。

标签: sql postgresql join


【解决方案1】:

绝对的。

当您在ON 子句中为LEFT JOIN 提供条件"noteReads"."id" IS NULL 时,它只考虑idNULL 的行。我猜这绝不是真的。

WHERE 子句中有条件时,if 过滤掉不匹配的行。那是非常不同。

注意:此解释特定于LEFT JOIN 中的第二个表(或RIGHT JOIN 中的第一个表,尽管我通常建议使用LEFT JOINs)。

【讨论】:

  • 谢谢!超级清楚而且很有道理! (上下文:我尝试修复由 ORM 生成的查询)。我会在 10 分钟内接受你的回答。
  • 就个人而言,我只会将JOIN 条件放在JOIN 子句中,否则您可能会混淆优化器。在您的情况下,您似乎只加入"notes"."id" = "noteReads"."noteId" 上的行。此外,如果您使用子查询,您可能会得到更快的响应,但这取决于您的 SQL 服务器和数据。使用 MySQL,如果您有一个只有几行匹配的大表,FROM 中的子查询会快得多。
  • @James 。 . . "noteReads"."userId" = 1 去哪里有很大的不同。我很确定正确的逻辑是这在ON 子句中。
【解决方案2】:

在这种情况下,我们必须了解,

  1. where 子句在左连接的结果集上。这意味着与加入条件不匹配的记录将右表字段填充为空,并且您正在过滤那些不匹配的记录。

  2. 如果您在左连接子句中使用相同的条件,它只会匹配那些具有空值的记录,因为您将其设置为匹配条件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-07
    • 2014-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    相关资源
    最近更新 更多