SQL:GROUPING SETS和PIVOT的替代和替换

时间:2014-11-24 18:07:29

标签: sql sql-server tsql subquery olap

我有这样的代码:

SELECT id, YEAR(datek) AS YEAR, COUNT(*) AS NUM
FROM Orders
GROUP BY GROUPING SETS
(
    (id, YEAR(datek)),
    id,
    YEAR(datek),
    ()
);

它给了我这个输出:

1   NULL    4
2   NULL    11
3   NULL    6
NULL    NULL    21
1   2006    36
2   2006    56
3   2006    51
NULL    2006    143
1   2007    130
2   2007    143
3   2007    125
NULL    2007    398
1   2008    79
2   2008    116
3   2008    73
NULL    2008    268
NULL    NULL    830
1   NULL    249
2   NULL    326
3   NULL    255

我需要做的是在没有“分组集”(也不是立方体或汇总)的情况下编写它,但结果相同。我想过写三个不同的查询并加入“联合”。我通过设置在组中尝试类似“null”的东西,但它不起作用。

SELECT id, YEAR(datek) AS rok, COUNT(*) AS NUM
FROM Orders
GROUP BY id, YEAR(datek)
UNION
SELECT id, YEAR(datek) AS rok, COUNT(*) AS NUM
FROM Orders
GROUP BY id, null
order by id, YEAR(datek)

我也有一个关于“PIVOT”的问题。什么样的语法可以用“PIVOT”替换查询?

感谢您的时间和所有答案!

1 个答案:

答案 0 :(得分:2)

你是对的,你需要单独的查询,虽然你实际上需要4,而不是GROUP BY NULL,只需按相应分组集中的列分组,并替换SELECT中的列与NULL

SELECT id, YEAR(datek) AS rok, COUNT(*) AS NUM
FROM Orders
GROUP BY id, YEAR(datek)

UNION ALL

SELECT id, NULL, COUNT(*) AS NUM
FROM Orders
GROUP BY id

UNION ALL

SELECT NULL, YEAR(datek), COUNT(*) AS NUM
FROM Orders
GROUP BY YEAR(datek)

UNION ALL

SELECT NULL, NULL, COUNT(*) AS NUM
FROM Orders
ORDER BY ID, Rok

关于PIVOT的替换,我认为最好的选择是使用条件聚合,例如而不是:

SELECT  pvt.SomeGroup,
        pvt.[A],
        pvt.[B],
        pvt.[C]
FROM    T
        PIVOT (SUM(Val) FOR Col IN ([A], [B], [C])) AS pvt;

你会使用:

SELECT  T.SomeGroup,
        [A] = SUM(CASE WHEN T.Col = 'A' THEN T.Val ELSE 0 END),
        [B] = SUM(CASE WHEN T.Col = 'B' THEN T.Val ELSE 0 END),
        [C] = SUM(CASE WHEN T.Col = 'C' THEN T.Val ELSE 0 END)
FROM    T
GROUP BY T.SomeGroup;