【问题标题】:Pivot table without aggregation and multiple pivot columns没有聚合和多个数据透视列的数据透视表
【发布时间】:2015-04-21 07:29:58
【问题描述】:

我遇到过这种情况,我认为最好的解决方案是使用数据透视函数,但我真的不知道该怎么做。或者也许有更好的方法来做到这一点......

我得到了这张表作为来源:

ID   | version | code | property | value
-----|---------|------|----------|------
  110|        1|    AA|     prop1|    10
  110|        1|    AA|     prop2|    20
  110|        1|    AA|     prop3|    30
  110|        1|    BB|     prop1|    10
  110|        1|    BB|     prop2|    40
  110|        1|    BB|     prop3|    20
  110|        2|    AA|     prop1|    50
  120|        1|    BB|     prop2|    60
  120|        2|    AA|     prop3|    80

我想要的结果如下:

ID   | version | code | prop1 | prop2 | prop3
-----|---------|------|-------|-------|------
  110|        1|    AA|     10|     20|    30
  110|        1|    BB|     10|     40|    20
  110|        2|    AA|     50|       |      
  120|        1|    BB|       |     60|      
  120|        2|    AA|       |       |    80

所以你看我不做聚合,只是对前 3 个表的透视。 这在 TSQL 中是否可行,我使用的是 SQL Server 2012。

【问题讨论】:

  • 总是prop1prop2prop3
  • “无聚合”很容易实现,如果每个组中最多只有一个值,并且您选择一个聚合,如果提供单个值,则返回相同的值 - 例如 @ 987654326@、MINMAX(我一般更喜欢后两者,因为它们适用于更广泛的类型)
  • @wewestthemenace 是的,列可以是静态的

标签: sql sql-server tsql sql-server-2012 pivot


【解决方案1】:

你想对 id、版本和代码进行分组,所以很简单:

Select * from TableName
pivot(max(value) for property in([prop1],[prop2],[prop3]))p

如果表格有更多列,那么您需要先选择正确的列:

;with cte as(Select id, version, code, property, value from TableName)
Select * from cte
pivot(max(value) for property in([prop1],[prop2],[prop3]))p

【讨论】:

    【解决方案2】:

    如果property 始终为prop1prop2prop3,您可以使用条件聚合来做到这一点:

    SELECT
          ID
        , Version
        , Code
        , MAX(CASE WHEN Property = 'prop1' THEN VALUE END) AS [prop1]
        , MAX(CASE WHEN Property = 'prop2' THEN VALUE END) AS [prop2]
        , MAX(CASE WHEN Property = 'prop3' THEN VALUE END) AS [prop3]
    FROM SampleData
    GROUP BY ID, Version, Code
    

    这是一种动态方法。阅读此article 以供参考。

    SQL Fiddle

    DECLARE @sql1 VARCHAR(4000) = ''
    DECLARE @sql2 VARCHAR(4000) = ''
    DECLARE @sql3 VARCHAR(4000) = ''
    
    SELECT @sql1 = 
    'SELECT
          ID
        , Version
        , Code
    '
    
    SELECT @sql2 = @sql2 +
    '   , MAX(CASE WHEN Property = ''' + Property + ''' THEN VALUE END) AS [' + Property + ']' + CHAR(10)
    FROM(
        SELECT DISTINCT Property FROM SampleData
    )t
    ORDER BY Property
    
    SELECT @sql3 =
    'FROM SampleData
    GROUP BY ID, Version, Code
    ORDER BY ID, Version, Code'
    
    PRINT(@sql1 + @sql2 + @sql3)
    EXEC (@sql1 + @sql2 + @sql3)
    

    【讨论】:

      【解决方案3】:
      declare @t table (Id int,version int,code varchar(10),property varchar(10),val int)
      insert into @t (Id,version,code,property,val)values (110,1,'AA','prop1',10),
      (110,1,'AA','prop2',20),(110,1,'AA','prop3',30),(110,1,'BB','prop1',10),
      (110,1,'BB','prop2',40),(110,1,'BB','prop3',20),(110,2,'AA','prop1',50),(120,1,'BB','prop2',60),
      (120,1,'AA','prop3',80)
      
      
      select Id,version,code,[prop1],[prop2],[prop3]
        from (
      select ID,version,code,property,val 
          from @t )t
      PIVOT(SUM(val)FOR Property IN ([prop1],[prop2],[prop3]))p
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-01
        • 2019-03-03
        • 2013-01-19
        • 2019-06-12
        • 1970-01-01
        相关资源
        最近更新 更多