2014-02-20 34 views
1

我想转置下面的表(示例)为1行,其中列名是行列1之一,并且行的值将是相应的列2row [x ]。转置2列多行到1行多列

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列,因为我有另一列以确保查询将按子集o进行查询f 300并为相同的ID创建多行。

任何人都做过吗?我有搜索,但我发现的一切是为了固定数量的列,并没有做我想找的东西。也许我没有使用正确的搜索关键字。

+0

没有,你指的问题是一个交叉表的列变为行与行获得计算成为行值修正列。 – Franck

回答

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,你需要做到以下几点到这是需要透视语法的​​格式的列名不同。

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 ║ 
╚════╩═══════╩════════╩══════════╝ 
+0

OMG动态支点,我没有想到那个。它完美地工作。幸运的是,这不是数百万条记录,我需要查询,否则会很慢。我需要将DECLARE @ID INT = 1;'更改为'DECLARE @ID INT'和'SET @ID = 1',并且丢弃了分号,所以对我的SQL版本进行了小修改。 – Franck

+0

以及内联声明的变量工作在SQL Server 2008+版本,因为你还没有提及你使用的是什么版本我认为你使用的是2008年:)无论如何,高兴它帮助:) –