#sql-server #tsql #pivot
#sql-server #tsql #сводная таблица
Вопрос:
У меня есть таблица :
Имя хоста | Приложение |
---|---|
SRV000001 | Приложение 1 |
SRV000001 | Приложение 2 |
SRV000002 | Приложение 3 |
SRV000003 | Приложение 1 |
SRV000003 | App4 |
SRV000003 | Приложение 5 |
Мне нужно свернуть / сгруппировать вокруг столбца Hostname, чтобы результат был примерно таким. Поскольку количество получаемых столбцов не является фиксированным, мне сложно использовать функцию pivot для этого.
Имя хоста | Col1 | Col2 | Col3 |
---|---|---|---|
SRV000001 | Приложение 1 | Приложение 2 | |
SRV000002 | Приложение 3 | ||
SRV000003 | Приложение 1 | App4 | Приложение 5 |
Ответ №1:
Столбцы могут быть пронумерованы с помощью ROW_NUMBER()
функции window для определения заголовков столбцов, таких как 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;