sql-server - 基于列值的透视,在多列中输出
问题描述
我有一张桌子:
主机名 | 应用 |
---|---|
SRV000001 | 应用程序1 |
SRV000001 | 应用程序2 |
SRV000002 | 应用程序3 |
SRV000003 | 应用程序1 |
SRV000003 | 应用程序4 |
SRV000003 | 应用程序5 |
我需要围绕主机名列进行旋转/分组,以便结果类似于。由于要获取的列数不固定,我发现很难在此上使用数据透视函数。
主机名 | Col1 | Col2 | Col3 |
---|---|---|---|
SRV000001 | 应用程序1 | 应用程序2 | |
SRV000002 | 应用程序3 | ||
SRV000003 | 应用程序1 | 应用程序4 | 应用程序5 |
解决方案
可以使用ROW_NUMBER()
窗口函数对列进行编号以确定列标题,例如Col1, Col2..
,然后可以通过使用此查询应用条件聚合:
SELECT [HostName],
MAX(CASE WHEN [rn]=1 THEN [Application] END) AS [Col1],
MAX(CASE WHEN [rn]=2 THEN [Application] END) AS [Col2],
MAX(CASE WHEN [rn]=3 THEN [Application] END) AS [Col3]
FROM(
SELECT *,
ROW_NUMBER() OVER
(PARTITION BY [HostName] ORDER BY [Application]) AS [rn]
FROM [t]
) AS t
GROUP BY [HostName]
查询可以通过以下代码块转换为动态查询:
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX)
SET @cols = ( SELECT STRING_AGG('MAX(CASE WHEN [rn]='+
CAST([rn] AS VARCHAR)+
' THEN [Application] END) AS [Col'+
CAST([rn] AS VARCHAR)+
']',',')
FROM (SELECT DISTINCT ROW_NUMBER() OVER
(PARTITION BY [HostName] ORDER BY [HostName]) AS [rn]
FROM [t] ) t );
SET @query =
N'SELECT [HostName],' + @cols +
N' FROM(
SELECT *,
ROW_NUMBER() OVER
(PARTITION BY [HostName] ORDER BY [Application]) AS [rn]
FROM [t]
) AS t
GROUP BY [HostName]';
EXEC sp_executesql @query;
推荐阅读
- python - 存储过程获取最后插入的行 python mysql 连接器
- java - 为什么我的 Azure 访问令牌 JWT 未能通过 Java 签名验证?
- python - 如何在 python 中比较 Twitter ID
- distribution - PyTorch 中 a, b>1 的 Beta 分布?
- c# - C# - 无法覆盖 ==
- mysql - WHERE 子句返回不正确的结果
- android - 如何在 android studio 3.1.2 中启用注释处理器
- c# - C# datagridview 列在排序时清除
- mysql - 使用“源 Table.sql”时,mariadb 控制台不接受变异元音(元音变音)
- c# - 在现有文件的详细信息选项卡中添加/编辑新的扩展属性