create pivot table with aggregates without a join

自作多情 提交于 2020-07-22 21:38:59

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!