我最近了解了用于在SQL Server中定义多个分组集的GROUPING SETS,CUBE和ROLLUP。
我要问的是我们在什么情况下使用这些功能?使用它们的好处和优点是什么?
SELECT shipperid, YEAR(shippeddate) AS shipyear, COUNT(*) AS numorders FROM Sales.Orders GROUP BY GROUPING SETS ( ( shipperid, YEAR(shippeddate) ), ( shipperid ), ( YEAR(shippeddate) ), ( ) ); SELECT shipperid, YEAR(shippeddate) AS shipyear, COUNT(*) AS numorders FROM Sales.Orders GROUP BY CUBE( shipperid, YEAR(shippeddate) ); SELECT shipcountry, shipregion, shipcity, COUNT(*) AS numorders FROM Sales.Orders GROUP BY ROLLUP( shipcountry, shipregion, shipcity );
首先,对于尚未阅读此主题的人:
话虽如此,不要将这些分组选项视为获取结果集的方式。 这些是性能工具 。
让我们以ROLLUP一个简单的例子为例。
ROLLUP
我可以使用以下查询来获取GrpCol的每个值的记录计数。
SELECT GrpCol, count(*) AS cnt FROM dbo.MyTable GROUP BY GrpCol
我可以使用以下查询来汇总“汇总”所有记录的数量。
SELECT NULL, count(*) AS cnt FROM dbo.MyTable
而且,UNION ALL如果我使用ROLLUP子句编写了第一个查询,则可以通过上述两个查询获得与获得的结果完全相同的结果(这就是为什么在其中放置NULL的原因)。
UNION ALL
实际上,将它作为两个不同的查询来执行可能会更方便,因为这样我可以将分组结果与总计分开。为什么我要把我的最终总数与其他结果混合在一起?答案是同时使用该ROLLUP子句会更有效。SQL Server将使用一个执行计划,该计划将一次计算所有聚合。将其与UNION ALL提供相同结果但使用效率较低的执行计划(两次表扫描而不是一次表扫描)的示例进行比较。
想象一下一个极端的例子,其中您正在处理一个巨大的数据集,以至于每次扫描数据都需要一个小时的时间。您基本上必须每天提供有关该数据的每个可能维度(切片的方式)的总计。啊哈!我敢打赌,这些分组选项之一正是您所需要的。如果将一次扫描的结果保存到特殊的模式布局中,则可以在一天的剩余时间内运行报告,而不保存结果。
所以我基本上是说您正在从事数据仓库项目。对于我们其他人来说,它大多属于“要知道的整洁的事情”类别。