преобразование строк в столбец для набора идентификаторов - PullRequest
1 голос
/ 23 мая 2019

Рассмотрим следующий запрос:

DECLARE @t1 TABLE(
    CompanyId INT, 
    DirectorName VARCHAR(100));

INSERT INTO @t1
   VALUES
      (1,'D11'),
      (1,'D12'),
      (1,'D13'),
      (1,'D14'),
      (1,'D15'),
      (1,'D16'),
      (2,'D21'),
      (2,'D22'),
      (2,'D23'),
      (2,'D24'),
      (2,'D25'),
      (2,'D26'),
      (2,'D27'),
      (2,'D28'),
      (2,'D29'),
      (2,'D210'),
      (3,'D31'),
      (3,'D32'),
      (3,'D33');

SELECT * FROM @t1 

Он просто возвращает companyId и набор директоров для этого Id.Как я могу сгенерировать вывод ниже:

 CompanyId | Director1| Director2| Director3|Director4| Director5| Director6| Director7| Director8| Director9| Director10|
-----------------------------------------------------------------------------------------------------------------------------
       1           D11        D12       D13       D14        D15         D16       NULL        NULL       NULL      NULL
       2           D21        D22       D23       D24        D25         D26       D27         D28        D29       D210 
       3           D31        D32       D33       NULL       NULL        NULL      NULL        NULL       NULL      NULL 

Что делает вышеупомянутый трюк с запросом, так это то, что количество директоров различно для каждой компании.В приведенном выше примере номер строки 2 имеет наибольшее количество директоров, что означает, что соответствующие столбцы для других идентификаторов в конечном выводе, эти строки будут нулевыми.Как я могу создать вышеуказанный вывод.

Просто чтобы прояснить, результат не будет выходить за пределы 10 столбцов (директоров) для каждого идентификатора (companyId) в этом примере.

Ответы [ 2 ]

2 голосов
/ 23 мая 2019

Вы можете использовать следующее решение, используя PIVOT:

SELECT CompanyId, [Director1], [Director2], [Director3], [Director4], [Director5], [Director6], [Director7], [Director8], [Director9], [Director10] 
FROM (
  SELECT CompanyId, DirectorName, 'Director' + CAST(ROW_NUMBER () OVER (PARTITION BY CompanyId ORDER BY CompanyId, DirectorName) AS VARCHAR(2)) AS column_name 
  FROM @t1
) st PIVOT (
  MIN(DirectorName) 
  FOR column_name IN ([Director1], [Director2], [Director3], [Director4], [Director5], [Director6], [Director7], [Director8], [Director9], [Director10])
) pt

демо на dbfiddle.uk

1 голос
/ 23 мая 2019

С использованием CTE , ROW_NUMBER и условной агрегации вы можете сделать это

Пока число директоров для каждой компании не превышает 10

;with cteGetDirectorNum
AS(
    select
         T.CompanyId
        ,T.DirectorName
        ,DirectorNum    ='Director'+CONVERT(VARCHAR(10), Row_Number()over( partition by T.CompanyId order by T.CompanyId, T.DirectorName))
    from
        @t1     T
)
SELECT
     N.CompanyId
    ,Director1      = MAX(CASE WHEN N.DirectorNum = 'Director1' THEN n.DirectorName ELSE NULL END)
    ,Director2      = MAX(CASE WHEN N.DirectorNum = 'Director2' THEN n.DirectorName ELSE NULL END)
    ,Director3      = MAX(CASE WHEN N.DirectorNum = 'Director3' THEN n.DirectorName ELSE NULL END)
    ,Director4      = MAX(CASE WHEN N.DirectorNum = 'Director4' THEN n.DirectorName ELSE NULL END)
    ,Director5      = MAX(CASE WHEN N.DirectorNum = 'Director5' THEN n.DirectorName ELSE NULL END)
    ,Director6      = MAX(CASE WHEN N.DirectorNum = 'Director6' THEN n.DirectorName ELSE NULL END)
    ,Director7      = MAX(CASE WHEN N.DirectorNum = 'Director7' THEN n.DirectorName ELSE NULL END)
    ,Director8      = MAX(CASE WHEN N.DirectorNum = 'Director8' THEN n.DirectorName ELSE NULL END)
    ,Director9      = MAX(CASE WHEN N.DirectorNum = 'Director9' THEN n.DirectorName ELSE NULL END)
    ,Director10     = MAX(CASE WHEN N.DirectorNum = 'Director10' THEN n.DirectorName ELSE NULL END)
FROM
    cteGetDirectorNum N
GROUP BY N.CompanyId
...