如何在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 |
数据结构
网络
关系数据库管理系统
操作系统
Java
iOS
HTML
CSS
Android
Python
C语言编程
C++
C#
MongoDB
MySQL
Javascript
PHP