3

我使用 Microsoft SQL Server,但我想这个问题适用于所有 SQL 语言。如果我有:

SELECT OrderHeaderID
    ,isNull(Qty,0) AS Qty
FROM OrderHeader
LEFT JOIN (
    SELECT OrderHeaderID
    ,Sum(Qty) AS Qty
    FROM OrderDetail
    GROUP BY OrderHeaderID
) OrderDetail
ON OrderDetail.OrderHeaderID = OrderHeader.OrderHeaderID
WHERE Criteria = 'X'

那么在应用标准之前,是否会对所有 OrderDetail 行执行 GROUP BY?换句话说,我应该注意将标准应用于 GROUP BY 以及外部 SELECT 吗?

顺便说一句,如果您看到这行代码有任何改进,请也发表评论。

4

3 回答 3

3

关于您的第一个问题,很难说出优化器在编译查询时发现了什么。我认为您的内部聚合首先执行。

关于你的第二个问题,这两种选择可能更容易理解

SELECT OrderHeader.OrderHeaderID
      ,isNull(Sum(OrderDetail.Qty),0) AS Qty
 FROM OrderHeader
      LEFT JOIN OrderDetail
        ON OrderDetail.OrderHeaderID = OrderHeader.OrderHeaderID
WHERE OrderHeader.Criteria = 'X'
GROUP BY OrderHeader.OrderHeaderID

或者

select OrderHeaderId,
       IsNull(
         (Select sum(qty) from OrderDetails d 
           where d.OrderHeaderId = OrderHeader.OrderHeaderId)
         ,0) as qty
  from OrderHeader
 where Criteria='X'
于 2012-12-30T20:04:13.640 回答
1

数据库可以自由地执行查询,只要它返回正确的结果。这就是为什么 SQL 被称为声明性语言的原因:您指定您想要的,而不是您想要的方式。

Criteria = 'X'但是,在这种情况下,如果您移至left join. 然后查询将包括没有任何 OrderDetails 的 OrderHeaders。所以数据库不能自由地做你建议的重构。

于 2012-12-30T20:01:05.793 回答
1

答案是“是” - 将左连接表的非键条件移动到ON子句中将提高性能,因为行将尽早从结果中删除,而不是在所有连接后让 where 子句过滤它进行,尤其是在对其他表进行进一步连接时。

于 2012-12-30T20:07:42.390 回答