Pivot Query根据列的值将行放入不同的列

时间:2014-02-18 15:08:55

标签: sql-server select pivot-table

有些设备会通过不同的人进行不同类型的检查。我的表有这些信息的DeviceID,InspectID,Date和PersosnID。每个设备都可以进行多种类型的检查,因此该设备的表格中将有多行。

    DeviceID     InspectID           Date                PersonID
    1            10                  1/1/2014            100
    1            20                  2/2/2014            200 
    2            10                  3/3/2014            300
    2            30                  4/4/2014            400 

我正在寻找创建表视图的数据透视查询,其中每个设备只有一行,所有类型的检查都显示在列中。假设我事先知道InspectIDs只有10,20和30。

DeviceID  Date10   PersonID10 Date20   PersonID20 Date30   PersonID30
1         1/1/2014 100        2/2/2014 200        NULL     NULL                            
2         3/3/2014 300        NULL     NULL       4/4/2014 400 

我认为这可以通过数据透视查询来完成,但我对于枢纽来说是非常新的。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

;WITH CTE1 AS
(
    SELECT DeviceID,'Date'+CAST(InspectID AS VARCHAR(5)) InspectID,[DATE],
    'Person'+ CAST(InspectID AS VARCHAR(5)) PersonId,PersonId PERSONNO
    FROM YourTable WHERE DeviceID=1
                UNION ALL
    SELECT DeviceID,'Date'+CAST(InspectID AS VARCHAR(5)) InspectID,[DATE],
    'Person'+ CAST(InspectID AS VARCHAR(5)),PersonId PERSONNO
    FROM YourTable WHERE DeviceID=2
)
SELECT DeviceID,
MIN(CASE WHEN InspectID ='Date10' THEN [DATE] END) Date10,
MIN(CASE WHEN PersonId ='Person10' THEN PERSONNO END) PersonId10, 
MIN(CASE WHEN InspectID ='Date20' THEN [DATE] END) Date20, 
MIN(CASE WHEN PersonId ='Person20' THEN PERSONNO END) PersonId20,
MIN(CASE WHEN InspectID ='Date30' THEN [DATE] END) Date30,  
MIN(CASE WHEN PersonId ='Person30' THEN PERSONNO END) PersonId30    
FROM CTE1
GROUP BY DeviceID

这是?SQLFiddle http://sqlfiddle.com/#!3/6fe3b/2

答案 1 :(得分:0)

  

从表中创建一个临时表

SELECT * INTO #TTT FROM 
(
    SELECT DeviceID,'Date'+CAST(InspectID AS VARCHAR(5)) InspectID,[DATE],
    'Person'+ CAST(InspectID AS VARCHAR(5)) PersonId,PersonId PERSONNO
    FROM #YourTable WHERE DeviceID=1
                UNION ALL
    SELECT DeviceID,'Date'+CAST(InspectID AS VARCHAR(5)) InspectID,[DATE],
    'Person'+ CAST(InspectID AS VARCHAR(5)),PersonId PERSONNO
    FROM #YourTable WHERE DeviceID=2
)TAB
  

现在为InspectId提供支持

DECLARE @colsL NVARCHAR (MAX)
SELECT @colsL = COALESCE (@colsL + ',[' + CAST(INSPECTID AS VARCHAR) + ']', '[' + CAST(INSPECTID AS VARCHAR) + ']')
FROM  #TTT 
group by INSPECTID
ORDER BY INSPECTID


DECLARE @FQuery NVARCHAR(MAX)
SET @FQuery =   '
                select * INTO NEW  from  
                (
                    select DEVICEID,INSPECTID,[DATE] from #TTT
                ) as p
                PIVOT
                ( 
                    MIN([DATE]) FOR  INSPECTID IN ('+@colsL+')   
                ) AS PT          
                '

EXECUTE sp_executesql @FQuery
  

现在,转向PersonId并从之前的DeviceId加入   透视表

DECLARE @colsL2 NVARCHAR (MAX)

SELECT @colsL2 = COALESCE (@colsL2 + ',[' + CAST(PERSONID AS VARCHAR) + ']', '[' + CAST(PERSONID AS VARCHAR) + ']')
FROM  #TTT
group by PERSONID
ORDER BY PERSONID


DECLARE @FQuery2 NVARCHAR(MAX) --@colsL get the INSPECTID columns 
SET @FQuery2 =  '    
                select PT.*,'+@colsL+'
                FROM  
                (
                    select DEVICEID,PERSONID,PERSONNO from #TTT
                ) as p
                PIVOT
                ( 
                    MIN(PERSONNO) FOR  PERSONID IN ('+@colsL2+')   
                ) AS PT   
                JOIN 
                (
                    SELECT * FROM NEW
                )AS N 
                ON PT.DEVICEID=N.DEVICEID      
                '

EXECUTE sp_executesql @FQuery2
  

现在你有了结果,但你必须应用其他一些逻辑   对列进行排序(因为列是动态的)。你能行的   将列作为(4,1),(5,2),(6,3)等等进行前端