【问题标题】:SQL pivot on both a value column and a bit columnSQL 透视值列和位列
【发布时间】:2021-09-20 20:03:29
【问题描述】:

我有一个这样的RawDataTable

Date Country Value Accurate
2000 ABW 4 true
2001 ABW 9 true
2002 ABW 8 true
2000 GBR 1 false
2001 GBR 3 true
2002 GBR 4 false

我在 SQL Server 中旋转它以获得以下格式:

Date ABW GBR
2000 4 1
2001 9 3
2002 8 4

但我也希望在回报中包含Accurate 列,也许分散开,以便每个国家/地区也有自己的Accurate 列,如下所示:

Date ABW GBR ABW Accurate GBR Accurate
2000 4 1 true false
2001 9 3 true true
2002 8 4 true false

到目前为止,我正在使用下面的查询对其进行旋转,但实际上不知道我想要做的事情是否可行,也不知道从哪里开始修改查询:

SELECT * 
FROM 
    (SELECT 
         [Date],
         [Country],
         [Value]
     FROM 
         RawDataTable) CountryVals
PIVOT 
    (SUM([Value])
         FOR [Country] IN ([ABW], [GBR])
    ) AS PivotTable

我将Accurate 作为第一列select 的第四列。我尝试将另一个枢轴加入到查询的末尾,但这没有用,我尝试在枢轴选择中添加该 col ......实际上我什至无法让枢轴为Accurate 工作,因为它是一个bit 类型而不是 decimal 例如所以不确定用什么代替 SUM

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    我通常发现使用条件 case 表达式来进行简单的旋转会容易得多,您可以轻松地剪切和粘贴重复的列。 Pivot 只是不直观的语法糖,SQL Server 无论如何都会在内部扩展为 case 表达式。

    select date,
        Max(case when country='ABW' then value end) ABW,
        Max(case when country='GBR' then value end) GBR,
        Max(case when country='ABW' then accurate end) ABWAccurate,
        Max(case when country='GBR' then accurate end) GBRAccurate
    from t
    group by date
    

    【讨论】:

    • 它实际上是一个动态语句,因此很容易将国家列表中的一个位置放在一个枢轴上,但我想我仍然可以动态创建上述格式 - 是的,它用 case 语句编写的方式对我的程序员头脑来说更有意义。
    • 是的,绝对是的,我经常使用动态枢轴进行报告,它们也更容易像这样构建,至少我发现是这样。
    【解决方案2】:

    以下是使用 pivot 的解决方案:

    这里是 sqlfiddle:multipivot

    ;WITH PIV1 AS
    (
      SELECT * FROM (
          SELECT    
            [Date],
            [Country],
            [Value]
          FROM RawDataTable
        ) CountryVals
        PIVOT (
          SUM([Value])
          FOR [Country]
          IN ([ABW],[GBR])
        ) AS PivotTable
      ), PIV2 AS
      (
        SELECT * FROM (
          SELECT    
            [Date],
            [Country],
            [Accurate]
          FROM RawDataTable
        ) CountryVals
        PIVOT (
          MAX([Accurate])
          FOR [Country]
          IN ([ABW],[GBR])
        ) AS PivotTable
      )
      
      SELECT PIV1.Date, PIV1.ABW, PIV1.GBR, PIV2.ABW AS [ABW Accurate] , PIV2.GBR [GBR Accurate]
      FROM PIV1 INNER JOIN PIV2 ON PIV1.[Date] = PIV2.[Date]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多