【问题标题】:SQL Double Pivot With Sum带总和的 SQL 双枢轴
【发布时间】:2018-04-27 13:14:34
【问题描述】:

我在 SQL Server Management Studio 17 中有一个数据集,它需要一些旋转才能将多行折叠成一行,以便于阅读和节省空间。每个唯一 id 都有一组代码作为值的运算符,目的是在最后的总列中显示结果。我已经用一组代码执行了一次主要的支点,但看起来我需要做第二个来进行进一步的折叠/合并。

这是一些未透视的数据

PO_NUM   u_id   CODE_1   CODE_2   VALUE
---------------------------------------
0M274316 1      3        9;13     150
0N274316 1      9        9        200000
0O274316 1      6        9        210000
0P274316 1      6        13       21000
0Q274316 1      6        9        50000.5
0R274316 1      15       9        0
0M274317 2      3        9;13     150
0N274317 2      9        9        300000
0O274317 2      6        9        220000
0P274317 2      6        13       22000
0Q274317 2      6        8        90000.5
0R274317 2      15       8        0

以具有第一个唯一 id 的示例枢轴为例,我得到:

PO_NUM    uid  CODE_1   CODE_2    6         9        15
-----------------------------------------------------
0M274316  1      3       9;13    210000    200000   0
0M274316  1              9       21000     NULL     NULL
0M274316  1              13      50000.5   NULL     NULL

我需要做的是另一个枢轴,将 '9;13' 作为列,并与值一起使用总和。我有这个初始的枢轴命令:

SELECT PO_NUM, CODE_1, CODE_2, VALUE from table
Pivot (max(VALUE) for CODE_2 in ([6],[9],[15])) pvt1

当我不包含 CODE_1 vals 时,它会按预期合并数据。但是尝试使用 CODE_2 添加第二个枢轴只会进一步混淆数据。如何使用第一个命令中的旋转数据进行第二次旋转? 预期输出为:

PO_NUM    uid    6         9        15    9;13    9(2)    13   total
------------------------------------------------------------------------
0M274316  1   281000.5   200000     0      150    null   null   481150.5

基本上,它们的行已折叠成一列,代码被分解为列。实际上,列会被重命名以避免与名称冲突,因此我使用 9(2) 只是为了显示数据仍然存在。

对修改感到抱歉。

【问题讨论】:

  • 请提供您的预期输出

标签: sql pivot sql-server-2017


【解决方案1】:

如果我理解正确,请使用条件聚合:

select po_num, u_id, code_2,
       max(case when code_1 = 3 then value end) as [3],
       max(case when code_1 = 6 then value end) as [6],
       max(case when code_1 = 9 then value end) as [9],
       max(case when code_1 = 15 then value end) as [15]
from t
group by po_num, u_id, code_2;

我认为这将使用pivot 表达为:

SELECT PO_NUM, u_id, CODE_2, [3], [6], [9], [15]
from table
Pivot (max(VALUE) for CODE_2 in ([3], [6], [9], [15])) pvt1;

【讨论】:

    【解决方案2】:

    你可以试试这个。

    DECLARE @MyTable TABLE(PO_NUM VARCHAR(10),  u_id int,  CODE_1  varchar(10), CODE_2 varchar(10),  VALUE DECIMAL(18,2))
    INSERT INTO @MyTable VALUES
    ('0M274316', 1, '3', '9;13', 150),
    ('0N274316', 1, '9', '9', 200000),
    ('0O274316', 1, '6', '9', 210000),
    ('0P274316', 1, '6', '13', 21000),
    ('0Q274316', 1, '6', '9', 50000.5),
    ('0R274316', 1, '15', '9', 0),
    ('0M274317', 2, '3', '9;13', 150),
    ('0N274317', 2, '9', '9', 300000),
    ('0O274317', 2, '6', '9', 220000),
    ('0P274317', 2, '6', '13', 22000),
    ('0Q274317', 2, '6', '8', 90000.5),
    ('0R274317', 2, '15', '8', 0)
    
    
    SELECT *, [6] + [9] + [15] + [9;13] + [9(2)] + [13] as total FROM (
    
        SELECT PO_NUM,u_id, CODE + ( CASE WHEN DENSE_RANK() OVER( PARTITION BY CODE ORDER BY C ) > 1 THEN '(' + CAST (  C  AS varchar(50)) + ')' ELSE '' END ) CODE, VALUE 
        FROM (
            SELECT MIN(PO_NUM) OVER(PARTITION BY u_id) PO_NUM, u_id, 1 C, CODE_1 CODE, VALUE FROM @MyTable 
            UNION ALL
            SELECT MIN(PO_NUM) OVER(PARTITION BY u_id) PO_NUM, u_id, 2 C, CODE_2 CODE, VALUE from @MyTable 
        ) T
    ) SRC
    PIVOT(SUM(VALUE) FOR CODE IN ( [6], [9], [15], [9;13], [9(2)], [13])) PVT
    

    结果:

    PO_NUM     u_id        6            9           15        9;13      9(2)        13          total
    ---------- ----------- ------------ ----------- --------- --------- ----------- ----------- -------------
    0M274316   1           281000.50    200000.00   0.00      150.00    460000.50   21000.00    962151.00
    0M274317   2           332000.50    300000.00   0.00      150.00    520000.00   22000.00    1174150.50
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多