[英]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的列数相乘,然后将Qty
和TotalCost
列的信息放在新列上?
What you need to do is to UNPIVOT, and then PIVOT your data. 您需要执行的操作是先取消存储,然后再存储数据。 Please, read this documentation: Using PIVOT and UNPIVOT .
请阅读此文档: 使用PIVOT和UNPIVOT 。
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:
要解决此问题,只需要在最终枢纽之前执行另外两个步骤即可:
[Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)]
[Qty (+)], [Qty (-)], [TotalCost (+)], [TotalCost (-)]
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: 您可以在它的小提琴中看到它的工作原理 ,并在此处获得完整的代码和说明:
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 (-)
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 *
,将Name
和DocType
列连接起来,如下所示:
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
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.