SQL Server中如何行转列实现用户-日期统计结果的矩阵展示?
SQL Server 实现行转列(用户为行、日期为列)
完全可以实现,SQL Server提供了PIVOT运算符来处理这种行转列的需求,根据日期是否固定,有两种实现方式:
1. 静态日期列(日期已知且固定)
如果你的日期范围是确定的(比如示例中的3-19、3-20),可以直接用静态PIVOT语法:
首先假设你已经有了分组后的结果集,比如通过CTE或者子查询获取:
WITH DailyCounts AS ( SELECT UserName AS [User], Date, COUNT(*) AS [COUNT] -- 替换成你的原始表和筛选条件 FROM YourOriginalTable GROUP BY UserName, Date ) SELECT [User], [3-19], [3-20] FROM DailyCounts PIVOT ( SUM([COUNT]) -- COUNT是聚合值,这里用SUM或MAX都可以,因为每个用户+日期组合只有一个值 FOR Date IN ([3-19], [3-20]) ) AS PivotTable;
2. 动态日期列(日期不固定或不确定)
如果日期是动态变化的,无法提前写死列名,可以用动态SQL来自动生成列:
DECLARE @Columns NVARCHAR(MAX), @SQL NVARCHAR(MAX); -- 获取所有不重复的日期,拼接成PIVOT需要的列格式 SELECT @Columns = STRING_AGG(QUOTENAME(Date), ', ') FROM (SELECT DISTINCT Date FROM YourOriginalTable) AS Dates; -- 拼接完整的动态SQL语句 SET @SQL = N' WITH DailyCounts AS ( SELECT UserName AS [User], Date, COUNT(*) AS [COUNT] FROM YourOriginalTable GROUP BY UserName, Date ) SELECT [User], ' + @Columns + ' FROM DailyCounts PIVOT ( SUM([COUNT]) FOR Date IN (' + @Columns + ') ) AS PivotTable;'; -- 执行动态SQL EXEC sp_executesql @SQL;
注:如果你的SQL Server版本低于2017,STRING_AGG不可用,可以用FOR XML PATH来拼接列名:
SELECT @Columns = STUFF(( SELECT ', ' + QUOTENAME(Date) FROM (SELECT DISTINCT Date FROM YourOriginalTable) AS Dates ORDER BY Date FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 2, '');
内容的提问来源于stack exchange,提问作者Charles Batschelet
相关产品推荐
相关产品推荐

