SQL Server 了解CUBE和ROLLUP之间的区别

bpzcxfmw  于 2022-12-26  发布在  其他
关注(0)|答案(5)|浏览(176)

我的作业要求我找出“每个日期写了多少张发票?”
我有点卡住了,向我的教授寻求帮助。她给我发了一封电子邮件,询问可以回答这个问题,“每种类型和版本已经制造了多少炉子?对于一个挑战,但没有额外的积分,包括炉子的总数。”
这是她发给我的问题:

SELECT STOVE.Type + STOVE.Version AS 'Type+Version'
, COUNT(*) AS 'The Count'
FROM STOVE
GROUP BY STOVE.Type + STOVE.Version WITH ROLLUP;

所以,我调整了这个查询,直到它满足我的需要。这是我得出的结果:

SELECT InvoiceDt
, COUNT(InvoiceNbr) AS 'Number of Invoices' 
FROM INVOICE 
GROUP BY InvoiceDt WITH ROLLUP 
ORDER BY InvoiceDt ASC;

它返回了我想要的结果。
无论如何,我决定仔细阅读ROLLUP子句,并从Microsoft中的一篇文章开始,文章中说ROLLUP子句类似于CUBE子句,但它与CUBE子句的区别如下:

  1. CUBE生成一个结果集,该结果集显示选定列中值的所有组合的聚合。
  2. ROLLUP生成一个结果集,该结果集显示选定列中值的层次结构的聚合。
    所以,我决定用CUBE替换查询中的ROLLUP,看看会发生什么。它们产生了相同的结果。我想这就是我感到困惑的地方。
    看起来,如果您使用的是我在这里所使用的查询类型,那么这两个子句之间没有任何实际差异。是这样吗?或者,我没有理解什么吗?当我阅读Microsoft文章时,我曾认为使用CUBE子句的结果应该有所不同。
bxjv4tth

bxjv4tth1#

您不会看到任何差异,因为您只汇总了一列。
第一个月
对于ROLLUP,它将具有以下输出:

YEAR, MONTH, DAY
YEAR, MONTH
YEAR
()

对于CUBE,它将具有以下内容:

YEAR, MONTH, DAY
YEAR, MONTH
YEAR, DAY
YEAR
MONTH, DAY
MONTH
DAY
()

CUBE基本上包含每个节点的每种可能的汇总方案,而ROLLUP将保持层次结构不变(因此它不会跳过MONTH而显示YEAR/DAY,而CUBE会)
这就是为什么您没有看到差异,因为您只有一个列要滚动。

kyks70gy

kyks70gy2#

我们可以通过一个简单的例子来理解ROLLUP和CUBE之间的区别。假设我们有一个表,其中包含学生的季度测试结果。在某些情况下,我们需要看到与季度对应的总数以及学生。以下是示例表

SELECT * INTO #TEMP
FROM
(
    SELECT 'Quarter 1' PERIOD,'Amar' NAME ,97 MARKS
    UNION ALL
    SELECT 'Quarter 1','Ram',88 
    UNION ALL
    SELECT 'Quarter 1','Simi',76 
    UNION ALL
    SELECT 'Quarter 2','Amar',94 
    UNION ALL
    SELECT 'Quarter 2','Ram',82 
    UNION ALL
    SELECT 'Quarter 2','Simi',71 
    UNION ALL
    SELECT 'Quarter 3' ,'Amar',95 
    UNION ALL
    SELECT 'Quarter 3','Ram',83 
    UNION ALL
    SELECT 'Quarter 3','Simi',77
    UNION ALL
    SELECT 'Quarter 4' ,'Amar',91 
    UNION ALL
    SELECT 'Quarter 4','Ram',84 
    UNION ALL
    SELECT 'Quarter 4','Simi',79
)TAB

1. ROLLUP(可以查找对应于一列的合计)

(a)得到每个学生在各方面的总成绩。

SELECT * FROM #TEMP
UNION ALL
SELECT PERIOD,NAME,SUM(MARKS) TOTAL
FROM #TEMP
GROUP BY NAME,PERIOD 
WITH ROLLUP
HAVING PERIOD IS NULL AND NAME IS NOT NULL 
// Having is used inorder to emit a row that is the total of all totals of each student

以下是(a)项的结果:

(b)如果你需要得到每个季度的总成绩

SELECT * FROM #TEMP
UNION ALL
SELECT PERIOD,NAME,SUM(MARKS) TOTAL
FROM #TEMP
GROUP BY PERIOD,NAME 
WITH ROLLUP
HAVING PERIOD IS NOT NULL AND NAME IS NULL

以下是(B)项的结果:

2. CUBE(在一个快照中查找季度总数和学生总数)

SELECT PERIOD,NAME,SUM(MARKS) TOTAL
FROM #TEMP
GROUP BY NAME,PERIOD 
WITH CUBE
HAVING PERIOD IS NOT NULL OR NAME IS NOT NULL

以下是CUBE的结果

现在你可能想知道ROLLUP和CUBE的真实的使用。有时我们需要一个报表,其中我们需要看到每个季度的总数和每个学生在一个镜头的总数。这里是一个例子
我稍微修改了上面的CUBE查询,因为我们需要两个合计的总和。

SELECT CASE WHEN PERIOD IS NULL THEN 'TOTAL' ELSE PERIOD END PERIOD,
CASE WHEN NAME IS NULL THEN 'TOTAL' ELSE NAME END NAME,
SUM(MARKS) MARKS
INTO #TEMP2
FROM #TEMP
GROUP BY NAME,PERIOD 
WITH CUBE

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + PERIOD + ']', 
               '[' + PERIOD + ']')
               FROM    (SELECT DISTINCT PERIOD FROM #TEMP2) PV  
               ORDER BY PERIOD    

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT * FROM 
             (
                 SELECT * FROM #TEMP2
             ) x
             PIVOT 
             (
                 SUM(MARKS)
                 FOR [PERIOD] IN (' + @cols + ')
            ) p;' 

EXEC SP_EXECUTESQL @query

现在,您将获得以下结果

jv4diomz

jv4diomz3#

这是因为您只有一个作为分组依据的列。
添加Group by InvoiceDt, InvoiceCountry(或任何可以给予更多数据的字段)。
使用Cube将为您提供每个InvoiceDt的Sum,您将获得每个InvoiceCountry的Sum。

sg24os4d

sg24os4d4#

你可以找到更多关于GROUPING SET,CUBE,ROLL UP. TL; DR他们只是以某种方式扩展GROUP BY + UNION ALL来获得聚合:)
https://technet.microsoft.com/en-us/library/bb510427(v=sql.105).aspx

tktrz96b

tktrz96b5#

所有投票的答案都是好的。
一个重要的区别是

  1. ROLLUP规范的N个元素对应于N +1个分组集。
    1.立方体规格的N个元素对应于2^N个分组集。
    Further reading see my article with respect to spark sql
    例如:
    商店ID、产品类型
    汇总相当于
GROUP BY store_id,product_type
 GROUPING SETS (
(store_id,product_type)
,(product_type)
, ())

对于2(n)个按列分组的分组集,分组集具有(n +1)= 3个列组合
立方体相当于

GROUP BY store_id,product_type
 GROUPING SETS (
(store_id,product_type)
,(store_id)
,(product_type)
, ())

对于按列分组的2(n)个分组集,分组集具有(2^n)= 4种列组合

相关问题