【问题标题】:SQL Self Join / Pivot table querySQL 自联接/数据透视表查询
【发布时间】:2019-07-17 16:41:20
【问题描述】:

我在 SQL Server 2016 中有以下 Table1:

SELECT Year, Type, Value From Table1

    Year  Type  Value
    2010  1     10
    2010  2     15
    2010  3     20
    2011  1     100
    2011  2     150
    2011  3     200

我想把它转换成下表:

Year  Type1  Type2  Type3
2010  10     15     20
2011  100    150    200

我认为我们可以通过自联接或数据透视表来实现这一点。实现这一目标的最佳方法是什么?

【问题讨论】:

  • 你有没有尝试过这些?两者都可以。如果只有几种类型,自连接很容易实现。但条件聚合会更好。如果您有多种类型或不确定您将拥有哪一种并且可以编写动态枢轴,请使用枢轴

标签: sql-server tsql pivot-table self-join


【解决方案1】:
CREATE TABLE #myTable (
[Year] int, [Type] int, [Value] int, [ExtraColumn] varchar(10));

INSERT INTO #myTable ([Year], [Type], [Value], [ExtraColumn]) 
VALUES (2010, 1, 10, 'I'), 
       (2010, 2, 15, 'G'), 
       (2010, 3, 20, 'N'), 
       (2011, 1, 100, 'O'), 
       (2011, 2, 150, 'R'), 
       (2011, 3, 200, 'E'); 

select Year, [1] as Type1, [2] as Type2, [3] as Type3 
from ( 
 select [Year], [Type], [Value] 
 from #myTable 
 ) t 
PIVOT ( SUM(Value) FOR [Type] IN ( [1], [2], [3] ) ) pvt;

-- OR
with myData as
( 
 select [Year], [Type], [Value] 
 from #myTable 
)
select Year, [1] as Type1, [2] as Type2, [3] as Type3 
from myData
PIVOT ( SUM(Value) FOR [Type] IN ( [1], [2], [3] ) ) pvt;

drop table #myTable;

【讨论】:

    【解决方案2】:

    假设你总是有 3 种类型,使用条件聚合是解决这个问题的简单方法。

    select [Year]
        , Type1 = Max(case when [Type] = 1 then Value end)
        , Type2 = Max(case when [Type] = 2 then Value end)
        , Type3 = Max(case when [Type] = 3 then Value end)
    from Table1
    group by [Year]
    order by [Year]
    

    【讨论】:

      【解决方案3】:
      select * 
      from myTable PIVOT ( SUM(Value) FOR [Type] IN ( [1], [2], [3] ) ) pvt;
      

      DbFiddle demo

      【讨论】:

      • 我在“myTable”中有一些额外的列。我怎么能忽略它们?即使我不使用它们,它们也会以某种方式影响最终输出。
      • @developer,你可以列出你想要的列,而不是使用 *(实际上这是推荐的方式,我很懒)。
      • 创建的表带有额外的列 CREATE TABLE #myTable ([Year] int, [Type] int, [Value] int, [ExtraColumn] varchar(10))。插入脚本:INSERT INTO #myTable ([Year], [Type], [Value], [ExtraColumn]) VALUES (2010, 1, 10, 'I'), (2010, 2, 15, 'G'), ( 2010, 3, 20, 'N'), (2011, 1, 100, 'O'), (2011, 2, 150, 'R'), (2011, 3, 200, 'E');选择查询:选择年份,[1]为Type1,[2]为Type2,[3]为Type3 from #myTable PIVOT ( SUM(Value) FOR [Type] IN ( [1], [2], [3] ) ) 列兵。不知何故,它没有显示正确的结果。
      • @developer,作为另一个答案添加,以免在此处混乱。
      【解决方案4】:

      假设你总是有 3 种类型,你可以在 SQL 中使用 PIVOT。

      这是基于您的示例的示例:

      if object_id('tempdb..#temp1') is not null
          drop table #temp1
      
      create table #temp1 (
           Year  int
           ,Type  int
           ,Value int
      )
      
      insert into #temp1 values 
          (2010,1,10),
          (2010,2,15),
          (2010,3,20),
          (2011,1,100),
          (2011,2,150),
          (2011,3,200)
      
      SELECT 
          Year
          , [1] AS Type1
          , [2] AS Type2
          , [3] AS Type3
      FROM   
          #temp1 p  
      PIVOT  
      (  
      sum(value)  
      FOR type IN  
      ( [1], [2], [3])  
      ) AS pvt  
      ORDER BY pvt.Year  
      

      结果如下:

      【讨论】:

        猜你喜欢
        • 2012-12-02
        • 2019-07-22
        • 2016-06-22
        • 2012-04-07
        • 1970-01-01
        • 1970-01-01
        • 2011-06-18
        • 2019-07-31
        相关资源
        最近更新 更多