【问题标题】:Explain the difference between these two SQL Queries?解释一下这两个 SQL 查询的区别?
【发布时间】:2020-01-04 09:15:59
【问题描述】:

第一个查询:

SELECT 
    d.id,
    d.brand_name,
    count(*) AS no_of_time_used
FROM content oc
LEFT JOIN drama d ON d.id = oc.drama_id
LEFT JOIN orders o ON o.id = oc.order_id
    AND o.fundraiser_id IS NOT NULL
GROUP BY drama_id
ORDER BY no_of_time_used DESC;

第二次查询:

SELECT 
    d.id,
    d.brand_name,
    count(*) AS no_of_time_used
FROM content oc
LEFT JOIN drama d ON d.id = oc.drama_id
LEFT JOIN orders o ON o.id = oc.order_id
WHERE o.fundraiser_id IS NOT NULL
GROUP BY drama_id
ORDER BY no_of_time_used DESC;

这些查询中只有一个区别是AND vs WHERE。在第一个查询中,我在第二个 JOIN 语句之后使用了 AND,而在第二个查询中,我使用 WHERE 代替了 AND

编辑:两个查询都返回不同的结果。

【问题讨论】:

  • @SushantYelpale 你确定吗?第二个查询将删除o.fundraiser_id 为空的所有行。第一个不会删除行,因为它是左连接。
  • 您介意提供两个查询的通用示例输入和单独的输出吗?我很确定通过这样做你会意识到不同之处。它是第二个查询可能返回的行数少于第一个...
  • 在第二个查询中,最后一个联接实际上是内部的,而不是左侧的。
  • 声明的重复不是这个问题的重复。例如,OP 很清楚这两个版本返回不同的结果。
  • @Shadow 。 . .不,这个问题是关于特定的过滤条件以及它如何影响结果。这与将JOIN 条件放在WHERE 子句中无关。

标签: mysql sql


【解决方案1】:

这里的问题是o.fundraiser_id IS NOT NULL的条件。

在您的查询中,条件位于ON 子句中:

FROM content oc LEFT JOIN
     drama d
     ON d.id = oc.drama_id LEFT JOIN
     orders o
     ON o.id = oc.order_id AND
        o.fundraiser_id IS NOT NULL

这表示无论orders 中是否存在匹配项,都保留content 中的所有行。即行数没有减少(相对于不使用LEFT JOIN orders)。

但是,这会影响来自orders。结果集中只有具有非NULL fundraiser_id 的行。如果没有这样的值,那么order_id 的列是NULL

第二种形式是更典型的形式:

FROM content oc LEFT JOIN
     drama d
     ON d.id = oc.drama_id LEFT JOIN
     orders o
     ON o.id = oc.order_id
WHERE o.fundraiser_id IS NOT NULL

这里的意图确实过滤掉了行。它将过滤掉fundraiser_id 不是NULL 的行。 NULL 值可以以两种方式出现:

  • orders 中的值可能是NULL
  • LEFT JOIN 可能找不到匹配的 order

这个版本过滤这些行,所以它改变了行数。至少,它会将第二个LEFT JOIN 变成INNER JOIN

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-30
    • 2021-02-25
    • 2017-01-30
    • 2012-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多