【问题标题】:Compress the pivot table result to one row in SQL将数据透视表结果压缩到 SQL 中的一行
【发布时间】:2021-02-27 17:07:52
【问题描述】:

我想在 SQL 数据透视表中得到如下所示的单行结果

+------------+-----------+------------+----------+ |请求ID | IT 评论 | SO 评论 |批准 | +------------+-----------+------------+----------+ | 11111 | 09-19 | 09-20 | 09-21 | +------------+-----------+------------+----------+

但是,我无法摆脱列中的空值:

+------------+-----------+------------+----------+ |请求ID | IT 评论 | SO 评论 |批准 | +------------+-----------+------------+----------+ | 11111 | 09-19 |空 |空 | | 11111 |空 | 09-20 |空 | | 11111 |空 |空 | 09-21 | +------------+-----------+------------+----------+

以下是我的查询,谁能解释一下如何修改我的查询?谢谢!

   SELECT [Request_ID] [Request ID]
        ,[IT Review]
        ,[SO Review]
        ,[Approved]
    FROM (
        SELECT *
        FROM [RptChange].[dbo].[tRequestsAudit] a
        JOIN (
            SELECT [reqID] [Request_ID]
                ,MIN([reqUpdateDt]) [UpdateDT]
                ,MIN([AuditID]) AS EarliestAuditID
                ,[reqStatus] SubStatus
            FROM [RptChange].[dbo].[tRequestsAudit]
            WHERE [reqID] = 102943
            GROUP BY [reqStatus]
                ,[reqID]
            ) sub ON sub.[EarliestAuditID] = a.AuditID
        ) sub2
    PIVOT(MIN([UpdateDT]) FOR sub2.reqStatus IN (
                [IT Review]
                ,[SO Review]
                ,[Approved]
                )) AS P

【问题讨论】:

标签: sql sql-server


【解决方案1】:

尝试替换

SELECT *

SELECT DISTINCT sub.Request_ID, sub.UpdateDT,a.reqStatus

类似的东西:

   SELECT [Request_ID] [Request ID]
        ,[IT Review]
        ,[SO Review]
        ,[Approved]
    FROM (
        SELECT DISTINCT sub.Request_ID, sub.UpdateDT,a.reqStatus
        FROM [RptChange].[dbo].[tRequestsAudit] a
        JOIN (
            SELECT [reqID] [Request_ID]
                ,MIN([reqUpdateDt]) [UpdateDT]
                ,MIN([AuditID]) AS EarliestAuditID
                ,[reqStatus] SubStatus
            FROM [RptChange].[dbo].[tRequestsAudit]
            WHERE [reqID] = 102943
            GROUP BY [reqStatus]
                ,[reqID]
            ) sub ON sub.[EarliestAuditID] = a.AuditID
        ) sub2
    PIVOT(MIN([UpdateDT]) FOR sub2.reqStatus IN (
                [IT Review]
                ,[SO Review]
                ,[Approved]
                )) AS P

【讨论】:

    【解决方案2】:
    SELECT [Request_ID] [Request ID]
            ,[IT Review]
            ,[SO Review]
            ,[Approved]
        FROM (
            SELECT sub.[Request_ID], sub.SubStatus, sub.UpdateDT
            FROM [dbo].[tRequestsAudit] a
            JOIN (
                SELECT [reqID] [Request_ID]
                    ,MIN([reqUpdateDt]) [UpdateDT]
                    ,MIN([AuditID]) AS EarliestAuditID
                    ,[reqStatus] SubStatus
                FROM [dbo].[tRequestsAudit]
                WHERE [reqID] = 1
                GROUP BY [reqStatus]
                    ,[reqID]
                ) sub ON sub.[EarliestAuditID] = a.AuditID
            ) sub2
        PIVOT(MIN([UpdateDT]) FOR sub2.SubStatus IN (
                    [IT Review]
                    ,[SO Review]
                    ,[Approved]
                    )) AS P
    

    【讨论】:

    • 感谢您的回复。我不想更改时间格式,但我想将数据透视表结果压缩为一行。
    【解决方案3】:

    可能是一种复杂的方法,但可以使用动态 SQL 压缩数据透视结果。 我设置的演示数据 (#data) 表示数据透视查询的输出,其中值最终交错排列,如问题中所述。

    这里的逻辑是,将表链接到自身的内部查询(相关子查询),其中获取有序结果集的前 1 个值,会将与该 ID 相关的所有结果放在一行中。动态 SQL 使您能够生成查询,而无需跨许多行和列进行硬编码。

    此解决方案是在 Transact SQL for MS SQL Server 中编写和测试的。

    -- create temp table to store demo data
    CREATE TABLE #data (Request_id int, 
                    [IT Review] nvarchar(5),
                    [SO Review] nvarchar(5),
                    [Approved] nvarchar(5)
                    )
    
    -- add data to demo table
    INSERT INTO #data
        VALUES (11111, '09-19', NULL, NULL),
            (11111, NULL, '09-20', NULL),
            (11111, NULL, NULL, '09-21')
    
    -- view demo data
    SELECT * FROM #data
    
    -- view the column name data that will be used to generate the query
    SELECT  name, column_id --INTO #table
    FROM tempdb.sys.columns 
        WHERE object_id =
            object_id('tempdb..#data')
            ORDER BY column_id
    
    -- declare variables to store the query in
    DECLARE @inner_query AS VARCHAR(MAX)
    DECLARE @outer_query AS VARCHAR(MAX)
    
    -- generate the inner query, the part to take the only non null value (top 1) based on 
    -- schema tables in the tempdb and relates this to the outer query via table alias t1. 
    -- ensure to exclude the id column as this is only for the outer query
    SET @inner_query = STUFF((SELECT '(SELECT TOP 1 ' + QUOTENAME(name) 
                                    + ' FROM #data WHERE [Request_id] = t1.[Request_id] 
                                    AND '
                                    + QUOTENAME(name) 
                                    + ' IS NOT NULL ) AS '
                                    + QUOTENAME(name) + ','
                        FROM tempdb.sys.columns 
                        WHERE object_id = object_id('tempdb..#data')
                            AND name != 'Request_id'
                        GROUP BY name, column_id
                        ORDER BY column_id
                        FOR XML PATH(''), TYPE
                        ).value('.', 'NVARCHAR(MAX)') 
                    ,1,1,'')
    
    -- view inner query
    SELECT @inner_query
    
    -- clean inner query to add required bracket at start and remove the comma at the end
    SET @inner_query = '(' + (SELECT SUBSTRING(@inner_query, 1, LEN(@inner_query)-1))
    
    -- view cleaned inner query
    SELECT @inner_query
    
    -- set the outer query, to which the inner query matches (using WHERE id=id)
    SET @outer_query = 'SELECT [Request_id], ' + @inner_query 
                + 'FROM #data t1 
                GROUP BY t1.[Request_id] ORDER BY t1.[Request_id]'
    
    -- view final query
    SELECT @outer_query
    
    -- execute the query
    EXECUTE(@outer_query)
    
    DROP TABLE #data
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-28
      • 1970-01-01
      相关资源
      最近更新 更多