【问题标题】:Combining columns with no common element (pivot) in SQL Server在 SQL Server 中组合没有公共元素(枢轴)的列
【发布时间】:2012-08-10 14:35:59
【问题描述】:

我正在努力寻找显示某些数据的最佳方式。

我的数据集如下所示:

Form  var1_Day  var1_WTD  var1_30Day  var2_Day  var2_WTD  var2_30Day ...
NA    null      null      null        77        448       2581
A1    166       791       4842        null      null      null
A2    304       1312      8365        null      null      null
A3    29        113       656         null      null      null

我正在尝试弄清楚如何像这样显示数据:

Var   Form  Day   WTD   30Day
var1  NA    null  null  null
var1  A1    166   791   4842
var1  A2    304   1312  8365
var1  A3    29    113   656
var2  NA    77    448   2581
var2  A1    null  null  null
var2  A2    null  null  null
var2  A3    null  null  null
...

我相信我将不得不使用数据透视表,但不知道从哪里开始。

谢谢你, 布拉德

【问题讨论】:

    标签: sql-server-2005 pivot unpivot


    【解决方案1】:

    虽然您可以像其他答案一样通过静态枢轴执行此操作,但如果您有很多列要转换,您可以使用动态枢轴:

    DECLARE @colsUnPivot AS NVARCHAR(MAX),
        @colsPivot AS NVARCHAR(MAX),
        @colsUnPivotNull as NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
    
    SET @colsUnPivot = stuff((select ','+quotename(C.name)
             from sys.columns as C
             where C.object_id = object_id('test') and
                   C.name like 'var%'
             for xml path('')), 1, 1, '')
    
    SET @colsUnPivotNull = stuff((select ', IsNull('+ quotename(C.name) +', 0)' + quotename(C.name)
             from sys.columns as C
             where C.object_id = object_id('test') and
                   C.name like 'var%'
             for xml path('')), 1, 1, '')
    
    SET @colsPivot = stuff((select DISTINCT ','+quotename(right((C.name), len(C.name)-5))
             from sys.columns as C
             where C.object_id = object_id('test') and
                   C.name like 'var%'
             for xml path('')), 1, 1, '')
    
    set @query 
      = ' 
          SELECT var, form,  '+ @colsPivot +'
          FROM
          (
            SELECT distinct substring(field, 1, 4) var, 
              --field,
              right((field), len(field)-5) as col,
              form,
              value
            from 
            (
              SELECT form, '+ @colsUnPivotNull + '
              FROM test
            ) t1
            unpivot 
            (
               value
               for field in (' + @colsUnPivot + ')
            ) unpvt 
          ) x
          pivot
          (
            sum(value)
            for col in ('+ @colsPivot + ')
          ) p
          ORDER BY var, form'
    
    execute(@query)
    

    SQL Fiddle with Demo

    这将获得要取消透视的列列表和执行时的透视。然后,如果您有很多列,则不必对值进行硬编码。

    【讨论】:

      【解决方案2】:

      其实你想要UNPIVOT

      就这样……

      select SUBSTRING(t,1,4) as Var, form, day, wtd, 30day 
      from yourtable
      unpivot ([day] for d in (var1_day,var2_day)) td
      unpivot ([wtd] for w in (var1_wtd,var2_wtd)) tw
      unpivot ([30day] for t in (var1_30day,var2_30day)) tt
      where SUBSTRING(d,1,4) = SUBSTRING(w,1,4)
      and  SUBSTRING(d,1,4) = SUBSTRING(t,1,4)
      

      【讨论】:

      • 谢谢,它工作得很好。我把它放在一个 sql-fiddle 中进行测试:sqlfiddle.com/#!3/caa7a/4
      • 如果你有超过 9 种类型的 var,你需要在最后调整过滤器 - 他们假设它来自 var1 - var9
      猜你喜欢
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多