【问题标题】:pivot table how to create the following数据透视表如何创建以下
【发布时间】:2016-12-17 20:20:31
【问题描述】:

我有这样的桌子

DisposalID  ReportID

242            84
243            84

我想看下面的方式

DisposalID  DisposalID     ReportID

242              243               84

我尝试使用数据透视表,但无法实现

select 
  *
from
(
SELECT [DisposalID]
,[ReportID]

FROM [ClearData_Test].[dbo].[DisposalConsolidatedView] WHERE [ReportID]=84
) DataTable
PIVOT
(
  Min(disposalid)
  FOR reportid
  IN ([84])
) PivotTable

它只给我最小值或最大值。任何帮助将不胜感激。

【问题讨论】:

    标签: sql-server pivot


    【解决方案1】:

    由于 PIVOT 需要聚合,因此您当前的查询将仅返回每个 DisposalId 的最小值/最大值。为了获得您想要的结果,您必须创建将用作新列标题的列。

    我会使用row_number() 并按您的ReportId 对数据进行分区。您正在使用的子查询将稍微更改为以下内容:

    SELECT [DisposalID]
      ,[ReportID]
      , 'DisposalId'
          +cast(row_number() over(partition by reportId
                                  order by disposalid) as varchar(10)) seq
    FROM [dbo].[DisposalConsolidatedView] 
    WHERE [ReportID]=84
    

    SQL Fiddle with Demo。这将创建一个包含值 DisposalId1DisposalId2 的列 - 这些新值将成为您的新列标题,然后您将聚合应用于现有的 DisposalId 列。

    最终的语法是:

    select DisposalId1, DisposalId2, ReportId
    from
    (
      SELECT [DisposalID]
        ,[ReportID]
        , 'DisposalId'
            +cast(row_number() over(partition by reportId
                                    order by disposalid) as varchar(10)) seq
      FROM [dbo].[DisposalConsolidatedView] 
      WHERE [ReportID]=84
      ) DataTable
    PIVOT
    (
      Min(disposalid)
      FOR seq IN (DisposalId1, DisposalId2)
    ) PivotTable;
    

    SQL Fiddle with Demo。这将给出一个结果:

    | DISPOSALID1 | DISPOSALID2 | REPORTID |
    |-------------|-------------|----------|
    |         242 |         243 |       84 |
    

    【讨论】:

    • 完美的工作就像一个魅力......还有一个小问题,如果有超过 2 个处置 ID 怎么办?他们可能有多达 20 个。
    • @user2954221 您要么必须硬编码 PIVOT IN 子句以包含最多 20 个列名,要么使用动态 SQL 来创建最终结果。这是我的一个动态 sql 示例的答案——stackoverflow.com/questions/19709206/…
    【解决方案2】:
    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    select @cols = STUFF((SELECT distinct ',' + QUOTENAME('DisposalID'+cast(seq as varchar(10))) 
                    from
                    (
                      select row_number() over(partition by [reportId] 
                                               order by disposalid) seq
                      from [ClearData_Test].[dbo].[DisposalConsolidatedView]
                    ) d
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')
    
    set @query = 'SELECT [ReportID],' + @cols + ' 
            from 
            (
              SELECT [ReportID], disposalid,
                ''disposalid''+
                  cast(row_number() over(partition by  [reportId] 
                                         order by disposalid) as varchar(10)) seq
              FROM  [ClearData_Test].[dbo].[DisposalConsolidatedView]
              where[ReportID]=''84''
            ) x
            pivot 
            (
               Min(disposalid)
                for seq in (' + @cols + ')
            ) p '
    
    execute sp_executesql @query;
    

    这就是我正在寻找的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 2014-08-14
      相关资源
      最近更新 更多