问题陈述:
您想在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 ;
输出结果
播放器 | title_type | total_titles |
罗杰·费德勒 | ATP巡回赛冠军 | 103 |
罗杰·费德勒 | 大满贯 | 20 |
罗杰·费德勒 | | 123 |
| | 123 |
ROLLUP为ROLLUP中列出的“ n”个列生成n + 1小计。在上面的示例中,在按玩家和title_type进行正常分组之后,ROLLUP函数汇总了所有title_type值,以便我们看到玩家“ Roger Federer”的大满贯级别总和。您可以在输出中看到以粗体显示的汇总行。
现在,我们将为表中的所有玩家应用ROLLUP函数,如下所示:
SELECT player, title_type, SUM(titles) As total FROM atp_titles GROUP BY ROLLUP (player,title_type) ORDER BY player,title_type;
输出结果
播放器 | title_type | total_titles |
安德烈·阿加西(Andre Agassi) | ATP巡回赛冠军 | 52 |
安德烈·阿加西(Andre Agassi) | 大满贯 | 8 |
安德烈·阿加西(Andre Agassi) | | 60 |
安迪·穆雷(Andy Murray) | ATP巡回赛冠军 | 46 |
安迪·穆雷(Andy Murray) | 大满贯 | 3 |
安迪·穆雷(Andy Murray) | | 49 |
安迪·罗迪克 | ATP巡回赛冠军 | 32 |
安迪·罗迪克 | 大满贯 | 0 |
安迪·罗迪克 | | 32 |
德约科维奇(Novak Djokovic) | ATP巡回赛冠军 | 81 |
德约科维奇(Novak Djokovic) | 大满贯 | 17 |
德约科维奇(Novak Djokovic) | | 98 |
皮特·桑普拉斯 | ATP巡回赛冠军 | 64 |
皮特·桑普拉斯 | 大满贯 | 14 |
皮特·桑普拉斯 | | 78 |
拉斐尔·纳达尔(Rafael Nadal) | ATP巡回赛冠军 | 86 |
拉斐尔·纳达尔(Rafael Nadal) | 大满贯 | 20 |
拉斐尔·纳达尔(Rafael Nadal) | | 106 |
罗杰·费德勒 | ATP巡回赛冠军 | 103 |
罗杰·费德勒 | 大满贯 | 20 |
罗杰·费德勒 | | 123 |
托马斯·穆斯特(Thomas Muster) | ATP巡回赛冠军 | 39 |
托马斯·穆斯特(Thomas Muster) | 大满贯 | 1 |
托马斯·穆斯特(Thomas Muster) | | 40 |
| | 586 |
ROLLUP函数允许我们执行部分汇总以减少计算的小计的数量。以下部分汇总的输出如下所示:
SELECT player, title_type, SUM(titles) As total FROM atp_titles GROUP BY ROLLUP (player,title_type) ORDER BY player,title_type;
输出结果
播放器 | title_type | total_titles |
安德烈·阿加西(Andre Agassi) | ATP巡回赛冠军 | 52 |
安德烈·阿加西(Andre Agassi) | 大满贯 | 8 |
安德烈·阿加西(Andre Agassi) | | 60 |
安迪·穆雷(Andy Murray) | ATP巡回赛冠军 | 46 |
安迪·穆雷(Andy Murray) | 大满贯 | 3 |
安迪·穆雷(Andy Murray) | | 49 |
安迪·罗迪克 | ATP巡回赛冠军 | 32 |
安迪·罗迪克 | 大满贯 | 0 |
安迪·罗迪克 | | 32 |
德约科维奇(Novak Djokovic) | ATP巡回赛冠军 | 81 |
德约科维奇(Novak Djokovic) | 大满贯 | 17 |
德约科维奇(Novak Djokovic) | | 98 |
皮特·桑普拉斯 | ATP巡回赛冠军 | 64 |
皮特·桑普拉斯 | 大满贯 | 14 |
皮特·桑普拉斯 | | 78 |
拉斐尔·纳达尔(Rafael Nadal) | ATP巡回赛冠军 | 86 |
拉斐尔·纳达尔(Rafael Nadal) | 大满贯 | 20 |
拉斐尔·纳达尔(Rafael Nadal) | | 106 |
罗杰·费德勒 | ATP巡回赛冠军 | 103 |
罗杰·费德勒 | 大满贯 | 20 |
罗杰·费德勒 | | 123 |
托马斯·穆斯特(Thomas Muster) | ATP巡回赛冠军 | 39 |