我试图将下表(示例)转换为1行,其中列名是行列1之一,行的值将对应列2row [x]。
Table
|--------------------------------|
| ID | Key | Value |
|--------------------------------|
| 1 | 'Color' | '13' |
| 1 | 'Access' | 'H' |
| 1 | 'LastCalc' | '17.06' |
| 2 | 'Choice' | 'done' |
| 2 | 'timeA' | '15:43' |
|--------------------------------|
现在我需要选择每个ID
选择ID 1会给我
|------------------------|
| Key | Value |
|------------------------|
| 'Color' | '13' |
| 'Access' | 'H' |
| 'LastCalc' | '17.06' |
|------------------------|
但我需要
|--------------------------------|
| Color | Access | LastCalc |
|--------------------------------|
| '13' | 'H' | '17.06' |
|--------------------------------|
使用该方法创建的列数量不会超过300列,因为我有另一列,以确保查询将按300的子集进行查询,并为同一ID创建多个行。
有人做过吗?我有搜索,但我发现的一切都是为了修复列数,并没有做我想要的。也许我没有使用正确的搜索关键字。
答案 0 :(得分:0)
测试数据
CREATE TABLE Test_Table_P(ID INT,[Key] VARCHAR(100),Value VARCHAR(100))
INSERT INTO Test_Table_P VALUES
(1,'Color','13'),(1,'Access','H'), (1,'LastCalc','17.06'),
(2,'Choice','done'),(2,'timeA','15:43')
<强>查询强>
假设您有一个变量@ID
,您想要所有列。
DECLARE @ID INT = 1;
获取给定ID的列,因为对于每个给定的ID,它将是不同的,您需要以[col1],[col2],[col3],.....
的格式对列名进行以下操作,这是Pivot语法所必需的。
DECLARE @Cols NVARCHAR(MAX);
SELECT @Cols = STUFF((SELECT ', ' + [Key] [text()]
FROM Test_Table_P
WHERE ID = t.ID
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)')
,1, 2, '')
FROM Test_Table_P t
WHERE ID = @ID
GROUP BY t.ID
将列存储在@Cols
变量中后,现在可以创建PIVOT查询并在查询中传递列名。如下......
DECLARE @sql NVARCHAR(MAX);
SET @sql = N'SELECT * FROM
(
SELECT ID, [Key], Value
FROM Test_Table_P
WHERE ID = @ID)Q
PIVOT (MAX(Value)
FOR [Key]
IN (' + @Cols + N')
)p'
构建查询后,您需要使用系统存储过程sp_executesql
执行它。并且由于sp_executesql具有自己的作用域,并且声明的任何变量对sp_executesql都不可见,因此您需要将@ID
作为其变量传递给sp_executesql。
EXECUTE sp_executesql @sql
,N'@ID INT'
,@ID
结果集
╔════╦═══════╦════════╦══════════╗
║ ID ║ Color ║ Access ║ LastCalc ║
╠════╬═══════╬════════╬══════════╣
║ 1 ║ 13 ║ H ║ 17.06 ║
╚════╩═══════╩════════╩══════════╝