问题
I think I am trying to do something that cannot be done. I am trying to create a pivot table, simultaneously doing two pivots by aggregating off two different columns. I have created a much simplified example to make the point more understandable.
CREATE TABLE two_aggregate_pivot (
ID INT,
category CHAR(1),
value INT
)
INSERT INTO dbo.two_aggregate_pivot
( ID, category, value )
VALUES (1, 'A', 100),
(1, 'B', 97),
(1, 'D', NULL),
(2, 'A', 86),
(2, 'C', 83),
(2, 'D', 81)
I can pivot to get the count of the categories as follows:
SELECT piv1.ID,
[A] AS cat_A,
[B] AS cat_B,
[C] AS cat_C,
[D] AS cat_D
FROM
(SELECT ID, category FROM dbo.two_aggregate_pivot) SRC
PIVOT
(
COUNT(category)
FOR category IN ([A],[B],[C],[D])
) piv1
And I get what I want.
ID cat_A cat_B cat_C cat_D
1 1 1 0 1
2 1 0 1 1
So too I can write a totally separate query, add the value column in the source select, and aggregate from MAX(value) instead, and get a pivot of max values.
ID val_A val_B val_C val_D
1 100 97 NULL NULL
2 86 NULL 83 81
But what I can't figure out is how to get them both.
ID cat_A cat_B cat_C cat_D val_A val_B val_C val_D
1 1 1 0 1 100 97 NULL NULL
2 1 0 1 1 86 NULL 83 81
I have seen examples here on stackoverflow using CASE statements to check IS NOT NULL, but that doesn't work for me I don't think, since I can have both missing values and extant values that are really NULL. I can create two CTEs, one with each PIVOT, then JOIN them. That gives me the table that I want, but it forces a clustered index scan of the table twice, and then of course the join operator. The table is quite large, and performance matters, so I want to try to find a way to do both pivots within the same clustered index scan.
Is that even possible?
回答1:
Perhaps a CROSS APPLY to unpivot your data. I should add, it would be a small matter to go dynamic.
Example
Select *
From (
Select ID
,B.*
From two_aggregate_pivot A
Cross Apply (values ('cat_'+category ,1)
,('val_'+category ,value)
) B (Item,Value)
) src
Pivot (sum(value) for item in ([cat_A],[cat_B],[cat_C],[cat_D],[val_A],[val_B],[val_C],[val_D]) ) pvt
Returns
ID cat_A cat_B cat_C cat_D val_A val_B val_C val_D
1 1 1 NULL 1 100 97 NULL NULL
2 1 NULL 1 1 86 NULL 83 81
来源:https://stackoverflow.com/questions/46692727/create-pivot-table-with-aggregates-without-a-join