如何在Oracle中生成组小计和大计?


问题陈述
您希望在 Oracle 中找出总计、小计和大计。

解决方案
Oracle ROLLUP 函数通过从右到左的方法执行多级分组,通过中间级别汇总到任何大计。为了演示 ROLLUP 函数,我们将创建一个表来保存网球运动员以及该运动员获得的 ATP 巡回赛冠军和大满贯冠军。

我们将首先为这个需求创建必要的数据。

示例

-- Drop table DROP TABLE atp_titles; -- Create table CREATE TABLE atp_titles (   player             VARCHAR2(100) NOT NULL,   title_type         VARCHAR2(100) NOT NULL,   titles             NUMBER NOT NULL);

示例

-- insert  ATP tour titles won by the player
INSERT INTO atp_titles VALUES('Roger Federer','ATP Tour Titles',103);
INSERT INTO atp_titles VALUES('Rafael Nadal','ATP Tour Titles',86);
INSERT INTO atp_titles VALUES('Novak Djokovic','ATP Tour Titles',81);
INSERT INTO atp_titles VALUES('Pete Sampras','ATP Tour Titles',64);
INSERT INTO atp_titles VALUES('Andre Agassi','ATP Tour Titles',52);
INSERT INTO atp_titles VALUES('Andy Murray','ATP Tour Titles',46);
INSERT INTO atp_titles VALUES('Thomas Muster','ATP Tour Titles',39);
INSERT INTO atp_titles VALUES('Andy Roddick','ATP Tour Titles',32);

示例

-- insert  grandslam titles won by the player
INSERT INTO atp_titles VALUES('Roger Federer','Grandslams',20);
INSERT INTO atp_titles VALUES('Rafael Nadal','Grandslams',20);
INSERT INTO atp_titles VALUES('Novak Djokovic','Grandslams',17);
INSERT INTO atp_titles VALUES('Pete Sampras','Grandslams',14);
INSERT INTO atp_titles VALUES('Andre Agassi','Grandslams',8);
INSERT INTO atp_titles VALUES('Andy Murray','Grandslams',3);
INSERT INTO atp_titles VALUES('Thomas Muster','Grandslams',1);
INSERT INTO atp_titles VALUES('Andy Roddick','Grandslams',0);

COMMIT;

现在我们将查看插入到 atp_titles 表中的几条记录。

示例

SELECT * FROM atp_titles ORDER BY 1;

输出

Andre Agassi    ATP Tour Titles     52
Andre Agassi    Grandslams          8
Andy Murray Grandslams          3
Andy Murray ATP Tour Titles     46
Andy Roddick    ATP Tour Titles     32
Andy Roddick    Grandslams          0
............................
............................

Oracle ROLLUP 表达式从右到左生成组小计以及大计。对于以上数据,假设我们想要确定球员“罗杰·费德勒”获得的总冠军数(即 ATP 巡回赛冠军 + 大满贯冠军)。

示例

SELECT player,title_type, SUM(titles) AS total_titles   FROM atp_titles  WHERE player = 'Roger Federer' GROUP BY ROLLUP (player,title_type) ORDER BY player,title_type ;

输出

球员
冠军类型
总冠军数
罗杰·费德勒
ATP 巡回赛冠军
103
罗杰·费德勒
大满贯
20
罗杰·费德勒
 
123
 
 
123

ROLLUP 为“n”个列出的列生成 n+1 个级别的子总计。在上面的示例中,在按球员和冠军类型进行常规分组后,ROLLUP 函数将所有冠军类型值汇总起来,以便我们看到球员“罗杰·费德勒”的大满贯级别的总和。您可以在输出中看到以粗体显示的汇总行。

现在我们将对表中的所有球员应用 ROLLUP 函数,如下所示

SQL

示例

SELECT player, title_type, SUM(titles) As total   FROM atp_titles GROUP BY ROLLUP (player,title_type) ORDER BY player,title_type;

输出

球员
冠军类型
总冠军数
安德烈·阿加西
ATP 巡回赛冠军
52
安德烈·阿加西
大满贯
8
安德烈·阿加西
 
60
安迪·穆雷
ATP 巡回赛冠军
46
安迪·穆雷
大满贯
3
安迪·穆雷
 
49
安迪·罗迪克
ATP 巡回赛冠军
32
安迪·罗迪克
大满贯
0
安迪·罗迪克
 
32
诺瓦克·德约科维奇
ATP 巡回赛冠军
81
诺瓦克·德约科维奇
大满贯
17
诺瓦克·德约科维奇
 
98
皮特·塞普里斯
ATP 巡回赛冠军
64
皮特·塞普里斯
大满贯
14
皮特·塞普里斯
 
78
拉斐尔·纳达尔
ATP 巡回赛冠军
86
拉斐尔·纳达尔
大满贯
20
拉斐尔·纳达尔
 
106
罗杰·费德勒
ATP 巡回赛冠军
103
罗杰·费德勒
大满贯
20
罗杰·费德勒
 
123
托马斯·穆斯特
ATP 巡回赛冠军
39
托马斯·穆斯特
大满贯
1
托马斯·穆斯特
 
40
 
 
586

ROLLUP 函数允许我们执行部分汇总以减少计算的子总计数量。以下部分汇总的输出如下所示

SQL

示例

SELECT player, title_type, SUM(titles) As total   FROM atp_titles GROUP BY ROLLUP (player,title_type) ORDER BY player,title_type;

输出

球员
冠军类型
总冠军数
安德烈·阿加西
ATP 巡回赛冠军
52
安德烈·阿加西
大满贯
8
安德烈·阿加西
 
60
安迪·穆雷
ATP 巡回赛冠军
46
安迪·穆雷
大满贯
3
安迪·穆雷
 
49
安迪·罗迪克
ATP 巡回赛冠军
32
安迪·罗迪克
大满贯
0
安迪·罗迪克
 
32
诺瓦克·德约科维奇
ATP 巡回赛冠军
81
诺瓦克·德约科维奇
大满贯
17
诺瓦克·德约科维奇
 
98
皮特·塞普里斯
ATP 巡回赛冠军
64
皮特·塞普里斯
大满贯
14
皮特·塞普里斯
 
78
拉斐尔·纳达尔
ATP 巡回赛冠军
86
拉斐尔·纳达尔
大满贯
20
拉斐尔·纳达尔
 
106
罗杰·费德勒
ATP 巡回赛冠军
103
罗杰·费德勒
大满贯
20
罗杰·费德勒
 
123
托马斯·穆斯特
ATP 巡回赛冠军
39

更新于: 2020-12-04

4K+ 次查看

启动你的 职业生涯

通过完成课程获得认证

开始
广告

© . All rights reserved.