SQL将未知数量的行值作为列淘汰

时间:2019-02-13 19:45:55

标签: sql pivot sql-server-2016

我正在将调查加载到数据库SQL Server(2016)中,不幸的是,检索数据的唯一方法是通过JSON。我想弄清楚我认为很简单的事情时遇到了麻烦。我有一个带有一些属性/ ID的表,然后最后两个字段是调查问题和答案,如下所示。通过SQL,我该如何完成以下任务?

-------------------------------
| Id | Question  | Answer     |
-------------------------------
| 1  | Q1        | A1         |
| 2  | Q2        | A2         |
| 3  | Q3        | A3         |
-------------------------------

我需要将其转换为以下格式。基本上将问题变成专栏。这可能吗?需要注意的是,行数是未知的,因此可能有50个调查问题。这是可变的。

-------------------------------
ID | Q1  | Q2 | Q3  |
-------------------------------
 1 | A1  | A2 | A3  |

谢谢

1 个答案:

答案 0 :(得分:0)

您可以使用动态Sql来透视未知的列名。

示例:

-- Test table
CREATE TABLE YourTable
(
    ID int primary key identity(1,1),
    OtherId int not null,
    Question varchar(30) not null,
    Answer varchar(30) not null
);

-- Sample Data
insert into YourTable (OtherId, Question, Answer) values
 (1, 'Q1', 'A1'), (1, 'Q2', 'A2'), (1, 'Q3', 'A3'), 
 (2, 'Q1', 'A4'), (2, 'Q2', 'A5'), (2, 'Q3', 'A6');

查询

DECLARE @Cols  AS NVARCHAR(MAX);
DECLARE @DynSql AS NVARCHAR(MAX);

SELECT @Cols = CONCAT(@Cols + ', ', QUOTENAME(Question))
FROM YourTable
GROUP BY Question
ORDER BY Question;

SET @DynSql = N'SELECT * 
FROM  
(
    SELECT OtherId, Question, Answer
    FROM YourTable
) src
PIVOT 
(
    MAX(Answer) 
    FOR Question IN (' + @Cols + N')
) pvt
ORDER BY OtherId';

-- SELECT @DynSql AS DynSql;
EXECUTE sp_executesql @DynSql;

结果:

OtherId Q1  Q2  Q3
1       A1  A2  A3
2       A4  A5  A6