SQL Server按年份拆分列统计总访问量并同行展示
解决T-SQL年份访问量行转列的问题
嘿,我来帮你搞定这个T-SQL行转列的需求!你现在的统计结果是按行输出每年的访问量,想要把它们合并到同一行、每个年份对应一列,这里有几种实用的方法,我给你一步步说明:
首先先补全你提供的临时表示例数据(方便测试):
CREATE TABLE #Events ( Col1 int PRIMARY KEY, Person Varchar(20), VisitYear INT, VisitInfo Varchar(20) ) INSERT INTO #Events VALUES (1, 'User1', 2017, 'Combo'), (2, 'User1', 2017, 'Single'), (3, 'User2', 2018, 'Combo'), (4, 'User3', 2017, 'Single'), (5, 'User2', 2019, 'Combo'), (6, 'User1', 2018, 'Single');
方法1:静态PIVOT(适用于已知固定年份的场景)
如果你的年份是确定的(比如只有2017、2018、2019这几年),直接用PIVOT函数就能快速实现行转列:
SELECT [2017] AS VisitCount_2017, [2018] AS VisitCount_2018, [2019] AS VisitCount_2019 FROM ( -- 先子查询统计每年的总访问量 SELECT VisitYear, COUNT(*) AS VisitCount FROM #Events GROUP BY VisitYear ) AS SourceData PIVOT ( -- 对统计的访问量做聚合(因为每个年份只有一行统计结果,SUM/MAX都可以) SUM(VisitCount) -- 指定要转成列的字段是VisitYear,列出所有目标年份 FOR VisitYear IN ([2017], [2018], [2019]) ) AS PivotTable;
方法2:动态PIVOT(适用于年份不固定的场景)
如果未来可能新增年份,或者年份数量很多不想手动罗列,用动态SQL自动生成列名会更灵活:
DECLARE @Columns NVARCHAR(MAX), @SQL NVARCHAR(MAX); -- 生成所有需要转成列的年份,格式为[2017],[2018],...(SQL Server 2017+支持STRING_AGG,旧版本可用STUFF+FOR XML PATH替代) SELECT @Columns = STRING_AGG(QUOTENAME(VisitYear), ',') FROM (SELECT DISTINCT VisitYear FROM #Events) AS Years; -- 拼接完整的动态SQL语句 SET @SQL = N' SELECT ' + @Columns + ' FROM ( SELECT VisitYear, COUNT(*) AS VisitCount FROM #Events GROUP BY VisitYear ) AS SourceData PIVOT ( SUM(VisitCount) FOR VisitYear IN (' + @Columns + ') ) AS PivotTable;'; -- 执行动态SQL EXEC sp_executesql @SQL;
方法3:条件聚合(新手友好,直观易懂)
如果你觉得PIVOT有点绕,用CASE配合聚合函数的条件聚合方法也能实现,逻辑更直白:
SELECT SUM(CASE WHEN VisitYear = 2017 THEN 1 ELSE 0 END) AS VisitCount_2017, SUM(CASE WHEN VisitYear = 2018 THEN 1 ELSE 0 END) AS VisitCount_2018, SUM(CASE WHEN VisitYear = 2019 THEN 1 ELSE 0 END) AS VisitCount_2019 FROM #Events;
这个逻辑很简单:对每一行数据判断年份,符合目标年份就计1,否则计0,最后用SUM把每个年份的计数加起来,就是该年份的总访问量。
内容的提问来源于stack exchange,提问作者user9268315
相关产品推荐
相关产品推荐

