在多个条件上旋转多个列

Posted

技术标签:

【中文标题】在多个条件上旋转多个列【英文标题】:Pivot Multiple Columns on Multiple Criteria 【发布时间】:2016-02-26 19:17:04 【问题描述】:

我是 SQL 新手,并且在学习过程中不断学习。我正在尝试基于 2 个列标题来透视表。

我当前的文件标题是年份、类型、设施、支付周期、成本中心、工作类别、小时、美元、单位。

我想创建一个透视表,将 Hours、Dolls 和 Units 分成列,但按年份和类型。

理想的结束列标题模板是:设施、支付周期、成本中心、工作类别、年份 - 类型小时、年份 - 类型美元、年份 - 类型单位。

谢谢!

【问题讨论】:

您能指定您将使用的 SQL 引擎吗? 我正在使用 MS SQL Server Management Studio 2012 能否请您提供示例输入数据和输出数据以及您已经完成的任何工作。 到目前为止,我所做的只是制作临时表 WHERE [year] = '2014' 和 [type] = 'actual' 并为每年和每种类型做同样的事情。然后引入所有列并左连接每个临时表和列标题的公共属性 如果您可以从输入表中提供一些示例数据,那将非常有帮助。 【参考方案1】:

您可以使用 SUM(或 MAX,具体取决于数据类型)和 CASE 来动态构建列,而不是使用数据透视表。

由于您没有提供任何数据,我只是编造了一些数据,并为简洁起见使用了所有整数。

--Sample Data
CREATE TABLE #test ([Year] INT, [Type] int, Facility int, [Pay Period] int, [Cost Center] int, [Job Class] int, [Hours] int, Dollars int, Units int)
INSERT INTO #test VALUES
(2013, 1, 1, 1, 1, 1, 5, 10, 15),
(2013, 2, 1, 3, 1, 1, 6, 20, 16),
(2013, 3, 2, 1, 1, 1, 7, 30, 17),
(2014, 1, 1, 1, 1, 1, 8, 40, 18),
(2014, 2, 1, 3, 1, 1, 9, 50, 19),
(2014, 3, 2, 1, 1, 1, 1, 60, 20),
(2014, 4, 2, 3, 1, 1, 2, 70, 10),
(2015, 1, 1, 1, 1, 1, 3, 80, 11),
(2015, 2, 1, 3, 1, 1, 4, 90, 12),
(2015, 3, 2, 1, 1, 1, 5, 10, 13),
(2015, 4, 2, 3, 1, 1, 6, 20, 14),
(2016, 1, 1, 1, 1, 1, 7, 30, 15),
(2016, 2, 1, 3, 1, 1, 8, 40, 16),
(2016, 3, 2, 1, 1, 1, 9, 50, 17),
(2016, 4, 2, 3, 1, 1, 1, 60, 18)


DECLARE @Columns NVARCHAR(MAX),
        @Sql NVARCHAR(MAX);

-- Build column variable using distinct Year, Type combinations for each year and type combination.
WITH cols AS 
(   SELECT  y.[Year],
            t.[Type]
    FROM    #test y, #test t
)
SELECT  @Columns = COALESCE(@Columns + ',','') 
            + CONCAT('SUM(CASE WHEN [Year] = ',[Year],' AND [Type] = ',[Type],' THEN [Hours] END) AS ',QUOTENAME(CONCAT([Year],' ',[Type],' - Hours'))) + ',' 
            + CONCAT('SUM(CASE WHEN [Year] = ',[Year],' AND [Type] = ',[Type],' THEN [Dollars] END) AS ',QUOTENAME(CONCAT([Year],' ',[Type],' - Dollars'))) + ',' 
            + CONCAT('SUM(CASE WHEN [Year] = ',[Year],' AND [Type] = ',[Type],' THEN [Units] END) AS ',QUOTENAME(CONCAT([Year],' ',[Type],' - Units')))
FROM    cols
GROUP BY [Year], [Type]
ORDER BY [Year], [Type];

-- Build dynamic sql that will select common fields, sum the dynamic columns, and group the data
SET @Sql = N'
    SELECT [Facility], [Pay Period], [Cost Center], [Job Class],'
    + @Columns + 
    'FROM #test
    GROUP BY [Facility], [Pay Period], [Cost Center], [Job Class]
'

-- Execute dyanamic query
EXEC(@Sql)

【讨论】:

以上是关于在多个条件上旋转多个列的主要内容,如果未能解决你的问题,请参考以下文章

在同一列上使用多个 WHERE 条件进行选择

如何在多个条件上加入,返回两个条件的所有组合

如何在 BigQuery 标准 SQL 中旋转多个列

在数据框的其他列上使用多个日期列和条件注释热图

在 Oracle DBMS 中的多个列上使用过滤条件连接表

在sql server中用一个条件更新多个列