使用没有连接的聚合创建数据透视表 [英] create pivot table with aggregates without a join

查看:45
本文介绍了使用没有连接的聚合创建数据透视表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想我正在尝试做一些无法完成的事情.我正在尝试创建一个数据透视表,通过聚合两个不同的列同时进行两个数据透视.我创建了一个非常简化的示例,以使这一点更易于理解.

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

我得到了我想要的.

ID  cat_A   cat_B   cat_C   cat_D
1   1       1       0       1
2   1       0       1       1

所以我也可以编写一个完全独立的查询,在源选择中添加值列,然后从 MAX(value) 聚合,并获得最大值的枢轴.

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

我在 stackoverflow 上看到过使用 CASE 语句检查 IS NOT NULL 的示例,但我认为这对我不起作用,因为我可以同时拥有缺失值和真正为 NULL 的现存值.我可以创建两个 CTE,每个 PIVOT 一个,然后加入它们.这给了我想要的表,但它强制对表进行两次聚集索引扫描,然后当然是连接运算符.该表非常大,性能很重要,所以我想尝试找到一种方法,在同一个聚集索引扫描中执行两个数据透视.

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.

这可能吗?

推荐答案

也许可以使用 CROSS APPLY 来取消数据透视.我应该补充一点,动态化是一件小事.

Perhaps a CROSS APPLY to unpivot your data. I should add, it would be a small matter to go dynamic.

示例

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

退货

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

这篇关于使用没有连接的聚合创建数据透视表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆