【发布时间】:2018-03-26 08:50:35
【问题描述】:
我觉得标题不够清楚(请指教)
假设我有这个假设的查询
SELECT
Name,
P.Amount,
count(DISTINCT PI.Id)
FROM Customer C
LEFT JOIN Purchase P ON C.Id = P.CustomerId
LEFT JOIN Flags F ON P.Id = F.PurchaseId AND F.Name = 'showItems'
LEFT JOIN PurchseItems PI ON PI.PurchseId = P.Id AND F.Value = 'TRUE'
WHERE C.Id = @customerId
GROUP BY Name, P.Amount, F.Value
或者
SELECT
Name,
P.Amount,
CASE WHEN F.Value = 'TRUE' THEN count(DISTINCT PI.Id) ELSE 0 END As ItemsCount
FROM Customer C
LEFT JOIN Purchase P ON C.Id = P.CustomerId
LEFT JOIN Flags F ON P.Id = F.PurchaseId AND F.Name = 'showItems'
LEFT JOIN PurchseItems PI ON PI.PurchseId = P.Id
WHERE C.Id = @customerId
GROUP BY Name, P.Amount, F.Value
无论如何,其中一个会帮助查询优化器吗?我正在使用 MS SQL 服务器。我想知道列列表上的条件是否有影响?
我的猜测是,如果F.Value 不是'True',则查询根本不必通过加入PurchaseItems。
编辑:在 Group by 中添加了 F.Value,因为它在每次购买时都是唯一的
我没有将其移近计数以保持查询或多或少相同。这个问题的想法是比较连接和选择列表的条件。
【问题讨论】:
-
当然您可以自己检查差异,只需运行两个查询。假设有一个 GROUP BY 你的第二个查询根本不会运行,它应该是
COUNT( DISTINCT CASE WHEN F.Value = 'TRUE' THEN PI.Id END As ItemsCount。否则无论如何都必须检查条件,最昂贵的操作将是 DISTINCT。 -
@dnoeth 您忘记在 SQL 中关闭括号。 :)
-
您不能拥有没有分组依据的聚合。编写有效的查询并比较执行计划。
-
语法仍然无效。
-
当您将 CASE 移动到 COUNT 中时,您将获得 working 查询,目前您只会收到一条错误消息:Msg 8120 Level 16 State 1 Line 1 列“F.Value”在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。
标签: sql sql-server query-optimization