假设你有“汽车总动员”的表几十万行, 和你想要做一个GROUP BY:T-SQL GROUP BY和COUNT,然后包括MAX从COUNT
SELECT CarID
, CarName
, COUNT(*) AS Total
FROM dbo.tbl_Cars
GROUP BY CarID
, CarName
该分组会给你带来类似于:
CarID CarName Total
1872 Olds 202,121
547841 BMW 175,298
9877 Ford 10,241
一切都很好。 我的问题,但是,是什么东西拿到 总计和MAX总到一个表,在性能和 清洁编码方面的最佳方式,让你有这样的结果:
CarID CarName Total Max Total
1872 Olds 202,121 202,121
547841 BMW 175,298 202,121
9877 Ford 10,241 202,121
一种方法将GROUP结果放入临时表 ,然后将临时表中的MAX读入局部变量。 但我想知道做到这一点的最佳方法是什么。
UPDATE
的公共表表达式似乎是最优雅的编写, 但类似@EBarr,我有限的测试表明一个显著降低性能。 所以我不会和CTE一起去。
由于@EBarr对COMPUTE
选项的链接表示功能 已被弃用,它似乎也不是最佳路线。
MAX值的局部变量选项和使用 临时表可能是我下降的路线,因为我不是 意识到它的性能问题。
有关我的用例的更多细节:它可能最终会成为其他SO问题的一系列问题。但足以说,我正在将一大部分数据加载到临时表中(因此tbl_Cars的一个子集是 进入#tbl_Cars,甚至#tbl_Cars可能会被进一步过滤 并对其执行聚合),因为我必须在单个存储的proc 内对其执行多个筛选 和聚合查询,该查询返回多个结果集。
更新2
@ EBarr的使用窗口函数的是好的和短。自我注释: 如果将RIGHT JOIN
用于外部参照表,则函数应从tbl_Cars中选择一列,而不是从'*'
中选择一列。
SELECT M.MachineID
, M.MachineType
, COUNT(C.CarID) AS Total
, MAX(COUNT(C.CarID)) OVER() as MaxTotal
FROM dbo.tbl_Cars C
RIGHT JOIN dbo.tbl_Machines M
ON C.CarID = M.CarID
GROUP BY M.MachineID
, M.MachineType
在速度方面,看起来很好,但在什么时候,你必须要 担心的读取次数?
你不能在索引视图中使用'MAX'(我一直要求5年 - http://connect.microsoft.com/SQLServer/feedback/details/267516/expand-aggregate-support-in-indexed-views-min-max)。 'theFieldBeingSearchedForMax'不在表中,它是输出的一部分(这是最高的计数)。 – 2012-02-09 19:41:33
只需重新阅读问题。我错读了它。更新SQL。 – EBarr 2012-02-09 19:42:58
- 抱歉,我未能在第一个查询中添加GROUP BY;我的错。 – mg1075 2012-02-09 19:52:20