use*_*867 2 sql-server aggregate group-by
我看过一些建议,但想知道在不使用子查询或不必要的联接的情况下从数据表中选择组、组总数、总计的最佳方法。
我最初的想法是这样的:
select product_family,
sum(widgets),
sum(widgets) over ()
from table.widget
group by product_family
Run Code Online (Sandbox Code Playgroud)
或以下内容:
select product_family,
sum(widgets),
sum(widgets) over (partition by all_field)
from table.widget
group by product_family
Run Code Online (Sandbox Code Playgroud)
显然这两种方法都不起作用。我知道一个分区的顺序可能比实际的行/组更高,但除了第一个示例将其留空之外,我不知道如何按“所有”进行分区。但是,它打破了 group by 语句。
我能找到的最好的是这样的:
select product_family,
family_sum,
sum(family_sum) over () as grand_sum
from (
select product_family, sum(widgets)
from table.widget
group by product_family
) as A
Run Code Online (Sandbox Code Playgroud)
不过,这仍然涉及子查询,这没关系。我只是觉得我在这里缺少一个简单的功能。
GROUP BY ROLLUP 做你想做的。
举个例子:
SELECT o.schema_id
, type_desc
, [Count Of Objects] = COUNT(o.object_id)
FROM sys.objects o
GROUP BY ROLLUP (o.schema_id, o.type_desc)
Run Code Online (Sandbox Code Playgroud)
这会产生以下输出:
?????????????????????????????????????????????????????? ??????? ? 架构_id ? 类型描述?对象数量? ?????????????????????????????????????????????????????? ??????? ? 1 ? PRIMARY_KEY_CONSTRAINT ?7 ? ? 1 ? 服务队列?3 ? ? 1 ? 用户表?8 ? ? 1 ? 空值 ?18 ? ? 4 ? 内部_表?16 ? ? 4 ? 系统表?72 ? ? 4 ? 空值 ?88 ? ? 空值 ?空值 ?106 ? ?????????????????????????????????????????????????????? ???????
所述NULL在前两列表示示出卷起的量。
为了使它“漂亮”,您可以对NULL汇总值使用一些替换:
SELECT [Schema Name] = CASE
WHEN s.name IS NULL THEN
'[Grand Total]'
ELSE s.name
END
, [Object Type] = CASE
WHEN o.type_desc IS NULL THEN
'[Total - ' + COALESCE(s.name, 'Overall') + ']' COLLATE SQL_Latin1_General_CP1_CI_AS
ELSE o.type_desc
END
, [Count of Objects] = COUNT(o.object_id)
FROM sys.objects o
INNER JOIN sys.schemas s ON o.schema_id = s.schema_id
GROUP BY ROLLUP (s.name, o.type_desc);
Run Code Online (Sandbox Code Playgroud)
?????????????????????????????????????????????????????? ???????????? ? 架构名称 ? 对象类型 ? 对象数 ? ?????????????????????????????????????????????????????? ???????????? ? 德博?PRIMARY_KEY_CONSTRAINT ?7 ? ? 德博?服务队列?3 ? ? 德博?用户表?8 ? ? 德博?[总计 - dbo] ? 18 ? ? 系统?内部_表?16 ? ? 系统?系统表?72 ? ? 系统?[总-系统] ? 88 ? ? [累计] ?[总 - 总] ? 106 ? ?????????????????????????????????????????????????????? ????????????
GROUP BY ROLLUP或者 - 更好 -GROUP BY GROUPING SETS如果您想要额外的行来显示总计,则最好。
如果您想要每一行(另一列)中的总计,那么您的查询需要进行细微调整。SUM(widgets)您可以在窗口函数中使用聚合:
select product_family,
sum(widgets) as total,
sum(sum(widgets)) over () as grand_total
from table.widget
group by product_family ;
Run Code Online (Sandbox Code Playgroud)