PIVOT таблица из строки в столбец - PullRequest
0 голосов
/ 23 января 2020

Привет, у меня есть таблица, похожая на приведенную ниже,

PId  |  PocType       |   pocDate
---------------------------------------
109  | POC - Start |   2018-09-20
109  | POC - Start |   2018-07-07
109  | POC - Start |   2018-11-15
101  | POC - Start |   2019-07-17
101  | POC - Start |   2019-07-01
100  | POC - Start |   2019-05-07
100  | POC - Start |   2019-05-07
100  | POC - Start |   2019-01-22
100  | POC - Start |   2019-03-20

Я хотел бы изменить ее на что-то похожее на это:

PId  |  Poc        |  pocDate  | procDate    | procDate   | procDate   | 
------------------------------------------------------------------------
109  | POC - Start | 2018-07-07 | 2018-09-20 | 2018-11-15 |            | 
101  | POC - Start | 2019-07-01 | 2019-07-17 |            |            | 
100  | POC - Start | 2019-01-22 | 2019-03-20 | 2019-05-07 | 2019-05-07 | 

Я пытаюсь использовать SQL PIVOT, но безуспешно.

select [PId],[pocDate]
from
(
  select [PId],[Poc],[pocDate]
  from #PocTable 
) x
pivot
(
  max(pocDate)
  for SystemProcedure in([pocDate])
)p

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 24 января 2020

Если вы все еще не можете понять это, вам поможет фрагмент кода ниже.

Схема из вашего вопроса:

SELECT * INTO #TABLE FROM (
SELECT 109  , 'POC - Start' ,  CAST( '2018-09-20' AS DATE) UNION ALL
SELECT 109  , 'POC - Start' ,  CAST( '2018-07-07' AS DATE) UNION ALL
SELECT 109  , 'POC - Start' ,  CAST( '2018-11-15' AS DATE) UNION ALL
SELECT 101  , 'POC - Start' ,  CAST( '2019-07-17' AS DATE) UNION ALL
SELECT 101  , 'POC - Start' ,  CAST( '2019-07-01' AS DATE) UNION ALL
SELECT 100  , 'POC - Start' ,  CAST( '2019-05-07' AS DATE) UNION ALL
SELECT 100  , 'POC - Start' ,  CAST( '2019-05-07' AS DATE) UNION ALL
SELECT 100  , 'POC - Start' ,  CAST( '2019-01-22' AS DATE) UNION ALL
SELECT 100  , 'POC - Start' ,  CAST( '2019-03-20' AS DATE)
)A(PId,PocType,pocDate)

Вам нужны динами c сводная таблица и вычисляемый столбец для имен столбцовых столбцов.

DECLARE @COLS VARCHAR(MAX) = '', @SQL VARCHAR(MAX) = ''

SELECT @COLS = @COLS+  QUOTENAME(SNO)+','  FROM (
SELECT DISTINCT 'pocDate'+ 
CAST( ROW_NUMBER() OVER(PARTITION BY PId ORDER BY pocDate ) AS VARCHAR(50)) SNO 
FROM #TABLE
)A

SELECT  @COLS = LEFT(@COLS, LEN(@COLS)-1)

SELECT  @SQL =  
'SELECT * FROM (
SELECT ''pocDate''
+ CAST( ROW_NUMBER() OVER(PARTITION BY PId ORDER BY pocDate ) AS VARCHAR(50)) SNO, * 
FROM #TABLE
)AS A
PIVOT
(
    MAX(pocDate) FOR SNO IN ('+@COLS+')
)PV '


EXEC (@SQL)

Результат:

+-----+-------------+------------+------------+------------+------------+
| PId |   PocType   |  pocDate1  |  pocDate2  |  pocDate3  |  pocDate4  |
+-----+-------------+------------+------------+------------+------------+
| 100 | POC - Start | 2019-01-22 | 2019-03-20 | 2019-05-07 | 2019-05-07 |
| 101 | POC - Start | 2019-07-01 | 2019-07-17 | NULL       | NULL       |
| 109 | POC - Start | 2018-07-07 | 2018-09-20 | 2018-11-15 | NULL       |
+-----+-------------+------------+------------+------------+------------+
0 голосов
/ 23 января 2020

Я бы использовал условную агрегацию, но ключ row_number():

select pid,
       max(case when seqnum = 1 then pocdate end) as pocdate_1,
       max(case when seqnum = 2 then pocdate end) as pocdate_2,
       max(case when seqnum = 3 then pocdate end) as pocdate_3,
       max(case when seqnum = 4 then pocdate end) as pocdate_4
from (select t.*,
             row_number() over (partition by pid, poc_type order by pocdate) as seqnum
      from t
     ) t
group by pid;
...