【问题标题】:Pivot Query that Puts the rows into different columns depending on the value of a column根据列的值将行放入不同列的透视查询
【发布时间】:2014-02-18 15:08:55
【问题描述】:

有些设备要经过不同人员的不同类型检查。我的表包含这些信息的 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 

我正在寻找创建表视图的数据透视查询,其中每个设备只有一行,并且所有类型的检查都显示在列中。假设我事先知道 InspectID 只有 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 

我认为这可以通过枢轴查询来完成,但我对枢轴很陌生。任何帮助将不胜感激。

【问题讨论】:

    标签: sql-server select pivot-table


    【解决方案1】:
    ;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

    【讨论】:

    • 但是如果我有 100000 个设备,你建议 UNION 100000 次呢???!!!
    • 我已经回答了你给定的桌子。 UNION 不反映设备的数量,但会影响日期。在这里,您需要为动态日期执行此操作。以下查询将对您有所帮助
    【解决方案2】:

    从你的表创建一个临时表

    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)等

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多