Как повернуть данные в SQL с несколькими условиями - PullRequest
1 голос
/ 30 января 2020

Я работаю с данными, где они выглядят так:

enter image description here

Я хочу повернуть их следующим образом:

enter image description here

Я написал таким образом:

select * 
  from (select * FROM records) as test
  PIVOT (
  max(value) for
  [Question_ID] in ((SELECT distinct [Question_ID] from records order by 1))) AS PivotTable

Не могли бы вы мне помочь?

Ответы [ 3 ]

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

Если вы знаете количество столбцов в PIVOT, вы можете напрямую жестко закодировать, как показано ниже.

SELECT * FROM
(
SELECT * FROM test
) t
PIVOT (
  MAX(value) for
  [Question_ID] in ([120],[122],[149],[150],[151],[189],[253],[554],[774] )) AS Pivot_Table

Если нет, вы должны использовать Dynamic Pivot table для неизвестного числа значений столбцов.

DECLARE 
    @columns NVARCHAR(MAX) = '', 
    @sql     NVARCHAR(MAX) = '';

-- select the QuestionIDs
SELECT 
    @columns+=QUOTENAME(Question_ID) + ','
FROM 
    test
GROUP BY Question_ID
ORDER BY Question_ID;

-- remove the last comma
SET @columns = LEFT(@columns, LEN(@columns) - 1);

-- construct dynamic SQL
SET @sql ='
SELECT * FROM   
(
    SELECT * FROM TEST
) t 
PIVOT(
     MAX(value) for 
     [Question_ID] IN ('+ @columns +')
) AS pivot_table;';

-- execute the dynamic SQL
EXECUTE sp_executesql @sql;

ПРОВЕРЬТЕ ДЕМО ЗДЕСЬ

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

Если вы уверены, что количество столбцов не изменится, вы можете использовать регистр

CREATE TABLE #TBL (ID INT, Question_ID INT, [Value] VARCHAR(20))
INSERT INTO #TBL VALUES
(1,149,'abc'),(1,150,'def'),(1,151,'aff'),(1,122,'www'),
(2,120,'add'),(2,150,'sub'),(2,189,'asf'),(3,253,'asd'),
(3,150,'gfre'),(3,554,'cvew'),(3,744,'qwert')
-- aNSWER
SELECT
        ID,
         MAX(CASE WHEN Question_ID = 149 THEN [Value] END) AS '149',
         MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
         MAX(CASE WHEN Question_ID = 151 THEN [Value] END) AS  '151',
         MAX(CASE WHEN Question_ID = 122 THEN [Value] END) AS '122',
         MAX(CASE WHEN Question_ID = 120 THEN [Value] END) AS '120',
         MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
         MAX(CASE WHEN Question_ID = 189 THEN [Value] END) AS '189',
         MAX(CASE WHEN Question_ID = 253 THEN [Value] END) AS '253',
         MAX(CASE WHEN Question_ID = 150 THEN [Value] END) AS '150',
         MAX(CASE WHEN Question_ID = 554 THEN [Value] END) AS '554',
         MAX(CASE WHEN Question_ID = 744 THEN [Value] END) AS '744'             
FROM #TBL
        GROUP BY ID
DROP TABLE #TBL

Выходные данные

ID  149   150   151  122    120   150   189   253   150   554   744
1   abc   def   aff  www    NULL  def   NULL  NULL  def   NULL  NULL
2   NULL  sub   NULL NULL   add   sub   asf   NULL  sub   NULL  NULL
3   NULL  gfre  NULL NULL   NULL  gfre  NULL  asd   gfre  cvew  qwert
0 голосов
/ 30 января 2020

вы получили свой wi sh результат

    select * 
  from (select * FROM #temp) as test--your table name replace with #temp
  PIVOT (
  max(value) for
  [Question_ID] in ([120],[122],[149],[150],[151],[189],[253],[554],[774] )) AS PivotTable

или если вы хотите динамически c ваш запрос

  DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(Question_ID) 
            FROM #temp c
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

        --print @cols
set @query = 'SELECT ID, ' + @cols + ' from 
            (
                select ID
                    , Question_ID
                    , [Value]
                from #temp
           ) x
            pivot 
            (
                 max([Value])
                for [Question_ID] in (' + @cols + ')
            ) p '


execute(@query)

drop table #temp


----------
...