问题陈述:
您想在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_typetotal_titles
罗杰·费德勒ATP巡回赛冠军103
罗杰·费德勒大满贯20
罗杰·费德勒123
123
ROLLUP为ROLLUP中列出的“ n”个列生成n + 1小计。在上面的示例中,在按玩家和title_type进行正常分组之后,ROLLUP函数汇总了所有title_type值,以便我们看到玩家“ Roger Federer”的大满贯级别总和。您可以在输出中看到以粗体显示的汇总行。
现在,我们将为表中的所有玩家应用ROLLUP函数,如下所示:
SQL:
示例SELECT player, title_type, SUM(titles) As total
FROM atp_titles
GROUP BY ROLLUP (player,title_type)
ORDER BY player,title_type;
输出结果播放器title_typetotal_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函数允许我们执行部分汇总以减少计算的小计的数量。以下部分汇总的输出如下所示:
SQL:
示例SELECT player, title_type, SUM(titles) As total
FROM atp_titles
GROUP BY ROLLUP (player,title_type)
ORDER BY player,title_type;
输出结果播放器title_typetotal_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