如何在T-SQL查询中同时获取分组标签计数与总结果数?
搞定T-SQL分组计数+总行数统计的需求
嘿,我明白你要的是什么——基于原查询的筛选条件,既要算出每个Tag出现了多少次,还要拿到符合条件的总记录行数对吧?这里有几种实用的实现方式,我给你拆解清楚:
方法一:用窗口函数一步到位(最推荐)
这种写法最简洁,不用绕弯子,直接用窗口函数COUNT(*) OVER()就能同时拿到分组计数和全局总行数:
SELECT Tag, COUNT(*) AS TagCount, -- 每个Tag的出现次数 COUNT(*) OVER() AS TotalRows -- 所有符合条件的记录总数 FROM [dbo].[_StanwellAlarms_U3] WHERE [TimeStamp] >= '2013-06-06 00:00:00' -- 划重点:不用转成NVARCHAR!如果TimeStamp是日期类型,直接传日期字符串就行,转字符串反而可能拖慢查询(用不上索引) AND [TimeStamp] < '2018-06-16 00:10:00' AND T = 'A' AND RG = 'R' GROUP BY Tag;
为啥这么写?
COUNT(*)配合GROUP BY Tag会统计每个Tag的出现次数COUNT(*) OVER()会忽略分组规则,直接计算整个筛选结果集的总行数,所以每一行的TotalRows都是同一个值,完美符合你的需求
方法二:子查询+联结(适合习惯传统写法的同学)
如果你更习惯用子查询的思路,也可以先把筛选后的数据存起来,再单独算总行数,最后拼在一起:
WITH FilteredData AS ( -- 先筛选出符合条件的所有记录,避免重复写WHERE条件 SELECT Tag FROM [dbo].[_StanwellAlarms_U3] WHERE [TimeStamp] >= '2013-06-06 00:00:00' AND [TimeStamp] < '2018-06-16 00:10:00' AND T = 'A' AND RG = 'R' ), TotalRecordCount AS ( -- 计算总记录数 SELECT COUNT(*) AS TotalRows FROM FilteredData ) SELECT fd.Tag, COUNT(fd.Tag) AS TagCount, trc.TotalRows FROM FilteredData fd -- 因为TotalRecordCount只有一行,交叉联结就能把总行数附加到每个Tag的结果上 CROSS JOIN TotalRecordCount trc GROUP BY fd.Tag, trc.TotalRows;
额外补充:如果要单独一行显示总行数
要是你需要在结果集最后单独加一行显示总记录数(比如做报表的时候),可以用UNION ALL实现:
-- 先查每个Tag的计数 SELECT Tag, COUNT(*) AS TagCount, NULL AS TotalRows FROM [dbo].[_StanwellAlarms_U3] WHERE [TimeStamp] >= '2013-06-06 00:00:00' AND [TimeStamp] < '2018-06-16 00:10:00' AND T = 'A' AND RG = 'R' GROUP BY Tag -- 再拼上总记录数的行 UNION ALL SELECT 'Total' AS Tag, NULL AS TagCount, COUNT(*) AS TotalRows FROM [dbo].[_StanwellAlarms_U3] WHERE [TimeStamp] >= '2013-06-06 00:00:00' AND [TimeStamp] < '2018-06-16 00:10:00' AND T = 'A' AND RG = 'R';
这样结果集最后会有一行标记为“Total”的记录,显示所有符合条件的总行数,非常直观。
内容的提问来源于stack exchange,提问作者Junius
相关产品推荐
相关产品推荐

