了解CUBE和ROLLUP之间的区别

我的任务要求我找出“每个date有多less发票?”

我有点卡住了,请求我的教授帮忙。 她给我发了一个问题,回答这个问题:“每种types和版本的炉子有多less?”对于一个挑战,但没有额外的要点,包括炉灶总数。

这是她给我的问题:

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条款,并从微软的文章开始。 它表示ROLLUP子句与CUBE子句类似,但是它以如下方式与CUBE子句区分开来:

  1. CUBE生成一个结果集,显示所选列中所有值的组合。
  2. ROLLUP生成一个结果集,显示所选列中值的层次结构的聚合。

所以,我决定用CUBEreplace查询中的ROLLUP,看看会发生什么。 他们产生了相同的结果。 我想这就是我感到困惑的地方。

看来,如果你使用的是我在这里的查询types,这两个子句之间没有任何实际的区别。 是对的吗? 或者,我不明白什么? 当我读完微软文章时,我曾经想过,使用CUBE子句,我的结果应该是不同的。

你不会看到任何区别,因为你只是在滚动一个列。 考虑一个我们做的例子

ROLLUP (YEAR, MONTH, DAY)

使用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会)

这就是为什么你没有看到有什么不同,因为你只有一个单一的列,你正在卷起。

希望有所帮助。

我们可以通过一个简单的例子来理解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 (可以find对应一列的总数)

(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.多维数据集 (查找总计四分之一以及学生在一个镜头)

 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 

现在你会得到以下结果

在这里输入图像说明

这是因为你只有一列,你正在分组。

Group by InvoiceDt, InvoiceCountry (或任何字段将给你更多的数据添加Group by InvoiceDt, InvoiceCountry

随着立方将给你每个发票DT的总和,你会得到每个发票国家的总和。

你可以find更多关于GROUPING SET,CUBE,ROLL UP的细节。 TL; DR他们只是扩展GROUP BY + UNION ALL在某些方面得到聚合:)

https://technet.microsoft.com/en-us/library/bb510427(v=sql.105).aspx