SQL Pivot用于多个值

时间:2016-11-13 23:05:19

标签: sql sql-server pivot pivot-table

这是我的数据

   Product_ID      Question      Answer
      1             When          Monday
      1             Where         Home
      1             Where         Work
      1              How          Car
      2             When          saturday
      2             Where         Home
      2             Where         Church
      2              How           Bus
      2              How           Walk

我希望数据如下所示

  Product_ID        When         Where   How
      1             Monday       Home    Car
      1             Monday       Work    Car
      2             Saturday     Home    Bus
      2             Saturday     Church  Bus
      2             Saturday     Home    Walk
      2             Saturday     Church  Walk

但我只能转动数据并且能够获得以下风格

  Product_ID        When         Where
      1             Monday       Work
      2             Saturday     Home

使用以下查询

 select * from 
(
select product_ID,question,answer from table1
) src
pivot (
max(answer)
for question in ([when],[where])
)piv

1 个答案:

答案 0 :(得分:2)

正如评论中所提到的,这并不需要PIVOT。实现所需结果的一种方法(假设只有两个问题:'when'和'where')是使用子查询的自联接:

SELECT T1.Product_ID, T1.[When], T2.[Where]
FROM (
    SELECT Product_ID, Answer [When]
    FROM table1
    WHERE Question = 'When'
    ) T1
JOIN (
    SELECT Product_ID, Answer [Where]
    FROM table1
    WHERE Question = 'Where') T2 ON T2.Product_ID = T1.Product_ID;

或者,使用APPLY来实现同样的目的:

SELECT *
FROM (
    SELECT Product_ID, Answer [When]
    FROM table1
    WHERE Question = 'When'
    ) T1
CROSS APPLY (
    SELECT Answer [Where]
    FROM table1
    WHERE Product_ID = T1.Product_ID
    AND Question = 'Where') T2;

编辑:这是使用动态SQL实现所需结果的一种方法:

/* -- Sample data
CREATE TABLE table1 (Product_ID INT NOT NULL, Question VARCHAR(20) NOT NULL, Answer VARCHAR(20) NOT NULL);
INSERT table1 
    VALUES (1, 'When', 'Monday')
         , (1, 'Where', 'Home')
         , (1, 'Where', 'Work')
         , (1, 'How', 'Car')
         , (2, 'When', 'Saturday')
         , (2, 'Where', 'Home')
         , (2, 'Where', 'Church')
         , (2, 'How', 'Bus')
         , (2, 'How', 'Walk')
         , (3, 'Where', 'Park'); -- No other questions for this Product_ID
*/

DECLARE @SQL VARCHAR(MAX) = '', @cols VARCHAR(MAX) = '', @joins VARCHAR(MAX) = '', @coalesce VARCHAR(MAX) = 'COALESCE';
SELECT @coalesce += CASE RN WHEN 1 THEN '(' ELSE ',' END + 'T' + CAST(RN AS VARCHAR(4)) + '.Product_ID'
     , @cols += ', T' + CAST(RN AS VARCHAR(4)) + '.' + QUOTENAME(Question)
     , @joins += 
       CASE RN 
        WHEN 1
        THEN '
FROM (SELECT Product_ID, Answer ' + QUOTENAME(Question) + ' FROM table1 WHERE Question = ''' + Question + ''') T1 '
        ELSE '
FULL JOIN (SELECT Product_ID, Answer ' + QUOTENAME(Question) + ' FROM table1 WHERE Question = ''' + Question + ''') T' + CAST(RN AS VARCHAR(4)) + ' ON T' + CAST(RN AS VARCHAR(4)) + '.Product_ID = T1.Product_ID'
       END
FROM (SELECT Question, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN FROM (SELECT DISTINCT Question FROM table1) T) T
ORDER BY RN;
SELECT @coalesce += ') Product_ID';

SELECT @SQL = 'SELECT ' + @coalesce + @cols + @joins;
PRINT @SQL;
EXEC(@SQL);