我有一个在 sql server 中生成以下结果的查询。并且需要将数据从 4 行转置为单行。
当我尝试使用 pivot 函数和 case 语句再次获取 4 行的空值时。请帮助我获得它的想法。
ID No Name Letter Answer CMT
123 103 A1 A Low Abc
123 103 A2 B High Abc
123 103 A3 A Medium Cde
123 103 A4 C Low Hhj
预期的O / P:
ID No Name1 Letter1 Answe1 CMT1 Name2 Letter2 Ans2 Cmt2 Name3 Letter3 ans3 cmt3 name4 letter4 ans4 cmt4
123 103 A1 A Low Abc A2 B High Abc A3 A Medium Cde A4 C Low Hhj
WITH myData AS
(
SELECT ID,
No,
Name,
Letter,
Answer,
CMT,
ROW_NUMBER() OVER (PARTITION BY Id,No ORDER BY ID, No) rn
FROM myTable
)
SELECT ID,
No,
MAX(CASE WHEN rn = 1 THEN Name END) name1,
MAX(CASE WHEN rn = 1 THEN Letter END) Letter1,
MAX(CASE WHEN rn = 1 THEN Answer END) Answer1,
MAX(CASE WHEN rn = 1 THEN CMT END) CMT1,
MAX(CASE WHEN rn = 2 THEN Name END) name2,
MAX(CASE WHEN rn = 2 THEN Letter END) Letter2,
MAX(CASE WHEN rn = 2 THEN Answer END) Answer2,
MAX(CASE WHEN rn = 2 THEN CMT END) CMT2,
MAX(CASE WHEN rn = 3 THEN Name END) name3,
MAX(CASE WHEN rn = 3 THEN Letter END) Letter3,
MAX(CASE WHEN rn = 3 THEN Answer END) Answer3,
MAX(CASE WHEN rn = 3 THEN CMT END) CMT3,
MAX(CASE WHEN rn = 4 THEN Name END) name4,
MAX(CASE WHEN rn = 4 THEN Letter END) Letter4,
MAX(CASE WHEN rn = 4 THEN Answer END) Answer4,
MAX(CASE WHEN rn = 4 THEN CMT END) CMT4
FROM myData
GROUP BY Id, No;
ID | 没有 | 姓名1 | 字母1 | 回答1 | CMT1 | 姓名2 | 字母2 | 答案2 | CMT2 | 姓名3 | 字母3 | 答案3 | CMT3 | 姓名4 | 字母4 | 回答4 | CMT4 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
123 | 103 | A1 | A | 低 | Abc | A2 | 乙 | 高 | Abc | A3 | A | 中等 | Cde | A4 | C | 低 | Hhj |
我不建议使用“pivot”来满足这种需求。虽然这乍一看可能很复杂,但使用“条件聚合”(聚合函数内的 case 表达式)实现输出会更容易:
SELECT
ID
, No
, MAX(CASE WHEN Name = 'A1' THEN Name END) AS Name1
, MAX(CASE WHEN Name = 'A1' THEN Letter END) AS Letter1
, MAX(CASE WHEN Name = 'A1' THEN Answer END) AS Answer1
, MAX(CASE WHEN Name = 'A1' THEN CMT END) AS CMT1
, MAX(CASE WHEN Name = 'A2' THEN Name END) AS Name2
, MAX(CASE WHEN Name = 'A2' THEN Letter END) AS Letter2
, MAX(CASE WHEN Name = 'A2' THEN Answer END) AS Answer2
, MAX(CASE WHEN Name = 'A2' THEN CMT END) AS CMT2
, MAX(CASE WHEN Name = 'A3' THEN Name END) AS Name3
, MAX(CASE WHEN Name = 'A3' THEN Letter END) AS Letter3
, MAX(CASE WHEN Name = 'A3' THEN Answer END) AS Answer3
, MAX(CASE WHEN Name = 'A3' THEN CMT END) AS CMT3
, MAX(CASE WHEN Name = 'A4' THEN Name END) AS Name4
, MAX(CASE WHEN Name = 'A4' THEN Letter END) AS Letter4
, MAX(CASE WHEN Name = 'A4' THEN Answer END) AS Answer4
, MAX(CASE WHEN Name = 'A4' THEN CMT END) AS CMT4
FROM mytable
GROUP BY
ID
, No
;
对于动态sql:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@colNames AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT DISTINCT ',' +
'MAX(CASE WHEN Name = ''' + Name + ''' THEN Name END) AS Name' + Name + ',' +
'MAX(CASE WHEN Name = ''' + Name + ''' THEN Letter END) AS Letter' + Name + ',' +
'MAX(CASE WHEN Name = ''' + Name + ''' THEN Answer END) AS Answer' + Name + ',' +
'MAX(CASE WHEN Name = ''' + Name + ''' THEN CMT END) AS CMT' + Name
FROM mytable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @colNames = STUFF((SELECT DISTINCT ',' +
'Name' + Name + ',Letter' + Name + ',Answer' + Name + ',CMT' + Name
FROM mytable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'')
SET @query = 'SELECT ID, No,' + @cols +
' FROM mytable GROUP BY ID, No'
EXECUTE(@query);
ID | 没有 | 姓名A1 | 字母A1 | 答案A1 | CMTA1 | 姓名A2 | 字母A2 | 答案A2 | CMTA2 | 姓名A3 | 字母A3 | 答案A3 | CMTA3 | 姓名A4 | 字母A4 | 答案A4 | CMTA4 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
123 | 103 | A1 | A | 低 | Abc | A2 | 乙 | 高 | Abc | A3 | A | 中等 | Cde | A4 | C | 低 | Hhj |