选择描述字段而不将其包含在 GROUP BY 子句中时 GROUP BY id 的最佳方法
Posted
技术标签:
【中文标题】选择描述字段而不将其包含在 GROUP BY 子句中时 GROUP BY id 的最佳方法【英文标题】:Best way to GROUP BY id while SELECTing a description field without including it in the GROUP BY clause 【发布时间】:2021-10-11 13:30:37 【问题描述】:我有两张桌子:
公司表
Id,
CompanyName
销售表:
Id,
CompanyId,
Date,
Value
我需要按日期和公司对销售额进行分组,并像这样显示:
CompanyId CompanyName Date Value
--------- -------------------- ---------- --------
1 Company 1 2021-10-01 2832.98
2 Company 2 2021-10-01 8112.81
1 Company 1 2021-10-02 2182.12
2 Company 2 2021-10-02 3521.11
我知道我可以通过这个轻松实现它
SELECT s.CompanyId, c.CompanyName, s.Date, SUM(s.Value) FROM Sale s
JOIN Company c on s.CompanyId = c.Id
GROUP BY s.Date, s.CompanyId, c.CompanyName
问题是当我在 GROUP BY 子句中包含 CompanyName
时,它会慢一个数量级。我也许可以通过添加一个新索引来规避它,但现在这不是一个选项。
我能够使用此查询使其运行得更快
SELECT
s.CompanyId,
(SELECT CompanyName FROM Company WHERE Id = s.CompanyId) as CompanyName
s.Date,
SUM(s.Value)
FROM Sale s
GROUP BY s.Date, s.CompanyId
但我想知道是否有更快/更好的方法。没有 CompanyName
的 group by 在 2 秒内运行,如果我将 CompanyName
添加到 GROUP BY 它会为查询增加 20 秒。使用我列出的最后一个查询,它会在大约 5 秒内运行。
【问题讨论】:
没有关于索引的信息和查询计划(您可以通过brentozar.com/pastetheplan 分享)我们无法帮助您。如果没有更好的索引,您不可能比现有的性能提高更多 您可以尝试将 行目标 添加到子查询中,这可能会有所帮助,具体取决于当前的执行计划。 【参考方案1】:将名称的查找推迟到分组之后? 未测试...
select i.CompanyId,c.CompanyName,i.Date,i.Value
From Company c join(
SELECT
s.CompanyId,
s.Date,
SUM(s.Value) as [Value]
FROM Sale s
GROUP BY s.Date, s.CompanyId) i
on i.CompanyId = c.CompanyId
【讨论】:
这可能与子查询选项具有相同的性能。引擎确实通常足够聪明,可以在两者之间转换 从这里很难分辨,你希望引擎能把它弄清楚,因为它有点明显。索引是唯一真正的解决方案。 我也认为这应该产生相同的速度,但实际上要快一点。我的查询比我向您展示的要复杂得多,我简化了它以专注于问题。我会接受你的回答,谢谢。 既然你已经有 CompanyId - 你不能只使用 MAX(c.CompanyName) 吗?以上是关于选择描述字段而不将其包含在 GROUP BY 子句中时 GROUP BY id 的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
列“在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中”]]
选择列表中的无效表达式(不包含在聚合函数或 GROUP BY 子句中)
列“在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中”