сводная таблица на основе значений столбцов с выводом в несколько столбцов

#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;
 

Demo