简体   繁体   English

T-SQL行到列:使用多个列聚合进行数据透视

[英]T-SQL Rows to Columns: Pivoting with multiple column aggregates

For example i have the following table: 例如我有下表:

CodInt          DocType         Qty (+)             Qty (-)             TotalCost (+)       TotalCost (-)
-----------------------------------------------------------------------------------------------------------
0208020015      2               NULL                -3.000000000        NULL                130.05000
0208020015      3               13056.000000000     79.000000000        547711.24000        3220.83000
0208020015      5               2.000000000         NULL                81.54000            NULL
0208020015      6               NULL                -11444.000000000    NULL                489120.75000

I need to group everything in a single row. 我需要将所有内容分组为一行。 So in the end I need the table to be CodInt + 24 Columns, 4 columns for each DocType (There's a total of 6 DocTypes). 因此,最后我需要将表设置为CodInt + 24列,每个DocType包含4列(总共6个DocType)。

I know i can probably do it with inner joins easily, but i wanted to know if there was a more simple/understandable way to do it since the inner join tend to be somewhat big. 我知道我可以轻松地使用内部联接来完成此操作,但是我想知道是否有更简单/可理解的方法来执行此操作,因为内部联接往往有些大。 I read about a PIVOT clause but i don't think i can use it in this case or haven't understood completely how it works. 我读到有关PIVOT子句的信息,但我认为我不能在这种情况下使用它,或者我不完全了解它的工作原理。

Example of what I'm looking for (shortened, there would still be 16 more columns): 我要查找的示例(简称,仍然会有16列):

CodInt          Qty1 (+)            Qty1 (-)        TotalCost1 (+)  TotalCost1 (-)  Qty2 (+)            Qty2 (-)            TotalCost2 (+)  TotalCost2 (-) .........
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
0208020015      NULL                NULL            NULL            NULL            NULL                -3.000000000        NULL            130.05000      .........

So my question is this: how can I group everything by CodInt , multiply the number of columns for each doctype and place the information of the columns Qty and TotalCost on the new columns? 所以我的问题是:如何将所有内容按CodInt ,将每个doctype的列数相乘,然后将QtyTotalCost列的信息放在新列上?

What you need to do is to UNPIVOT, and then PIVOT your data. 您需要执行的操作是先取消存储,然后再存储数据。 Please, read this documentation: Using PIVOT and UNPIVOT . 请阅读此文档: 使用PIVOT和UNPIVOT

Edition for the comments: pivoting with multiple aggregates 发表评论的版本:以多个聚合为中心

As I can see from the comments, the only problem that poses this case is that it's needed to PIVOT, aggregating four different columns. 从评论中可以看出,造成这种情况的唯一问题是PIVOT需要它,它汇总了四个不同的列。 To solve this problem it's only necessary to take two additional steps, before the final pivot: 要解决此问题,只需要在最终枢纽之前执行另外两个步骤即可:

  1. unpivot the columns to aggregate so that they move from the columns to the rows: in this case: [Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)] 取消透视图的聚合,以便它们从列移动到行:在这种情况下: [Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)]
  2. concatenate the names of the columns which has been unpivoted to the rows with the other pivoting column ( DocType ), thus obtaining all the combinations like [Qty (+) 1], [Qty (+) 2], [Qty (+) 3] , etc. 将未透视的列的名称与另一个透视列( DocType )连接起来,从而获得[Qty (+) 1], [Qty (+) 2], [Qty (+) 3]

You can see it working in this fiddle , and have the full code and explanations down here: 您可以在它的小提琴中看到它的工作原理 ,并在此处获得完整的代码和说明:

First step: unpivot 第一步:取消枢纽

With this query you move the columns [Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)] to different rows, to the new Name column 使用此查询,您可以将[Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)]列移动到不同的行,到新的Name

SELECT *
FROM 
    (SELECT 
        CodInt, DocType, [Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)] 
    FROM Test) Orig
UNPIVOT
    ( Value FOR Name IN 
        ([Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)])
    ) UnPiv

And you get something like this: 你会得到这样的东西:

CodInt   DocType  Value  Name
0208215  2         -3    Qty (-)
0208215  2        130    TotalCost (-)

Second step: get the names for the final aggregates 第二步:获取最终聚集的名称

It's just the same query as before, but, in the select list, instead of select * , concatenate the Name and DocType columns, like this: 它与以前的查询相同,但是在选择列表中,而不是select * ,将NameDocType列连接起来,如下所示:

SELECT 
    CodInt, 
    CAST(Name AS VARCHAR(20)) + ' ' + CAST(DocType AS VARCHAR(20)) Name,
    Value

At this point you get results that look like this: 此时,您将获得如下结果:

CodInt   Name               Value
0208215  Qty (-) 2          -3
0208215  TotalCost (-) 2    130

Third step, pivot the results 第三步,结果透视

Now that you have all the desired columns in their independent rows, you simply have to pivot them. 现在,所有所需的列都位于它们的独立行中,只需要旋转它们即可。 The final query looks like this ( the use of the CTE is for readability, is optional ): 最终查询如下所示( 使用CTE是为了提高可读性,是可选的 ):

WITH Unpivoted AS (
    SELECT 
        CodInt, 
        CAST(Name AS VARCHAR(20)) + ' ' + CAST(DocType AS VARCHAR(20)) Name,
        Value
    FROM 
        ( SELECT 
            CodInt, DocType, [Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)] 
        FROM Test ) UnPivSource
        UNPIVOT
        ( Value FOR Name IN 
            ([Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)])
        ) UnPiv
)
SELECT * FROM
( SELECT CodInt, Name, Value FROM Unpivoted ) PivotSource
PIVOT 
(SUM(Value) FOR NAME IN
    (
    [Qty (+) 1], [Qty (+) 2], [Qty (+) 3], [Qty (+) 4], [Qty (+) 5], [Qty (+) 6], 
    [Qty (-) 1], [Qty (-) 2], [Qty (-) 3], [Qty (-) 4], [Qty (-) 5], [Qty (-) 6],
    [TotalCost (+) 1], [TotalCost (+) 2], [TotalCost (+) 3], 
    [TotalCost (+) 4], [TotalCost (+) 5], [TotalCost (+) 6], 
    [TotalCost (-) 1], [TotalCost (-) 2], [TotalCost (-) 3], 
    [TotalCost (-) 4], [TotalCost (-) 5], [TotalCost (-) 6]
    )
) Pivoted

You get the final result, like this: 您将获得最终结果,如下所示:

CodInt   Qty (+) 1  Qty (+) 2  Qty (+) 3  Qty (+) 4  Qty (+) 5  Qty (+) 6  Qty (-) 1  Qty (-) 2  Qty (-) 3  Qty (-) 4  Qty (-) 5  Qty (-) 6  TotalCost (+) 1  TotalCost (+) 2  TotalCost (+) 3  TotalCost (+) 4  TotalCost (+) 5    TotalCost (+) 6  TotalCost (-) 1  TotalCost (-) 2  TotalCost (-) 3  TotalCost (-) 4  TotalCost (-) 5  TotalCost (-) 6
0208215  NULL       NULL       13056      NULL       2          NULL       NULL       -3         79         NULL       NULL       -11444     NULL             NULL             547711           NULL             82                 NULL             NULL             130              3221             NULL             NULL             489121
0208216  NULL       -8         127        NULL       NULL       928283     NULL       NULL       NULL       NULL       124        24         NULL             4567             2519             NULL             NULL               9292993          NULL             NULL             84               NULL             NULL             NULL

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM