Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句。如果是ROLLUP(A, B, C)的话,首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。如果是GROUP BY CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP BY操作。 grouping_id()可以美化效果:
Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句。
除本文内容外,你还可参考:
分析函数参考手册:
http://xsb.itpub.net/post/419/33028
分析函数使用例子介绍:
http://xsb.itpub.net/post/419/44634
SQL> create table t as select * from dba_indexes;
表已创建。
SQL> select index_type, status, count(*) from t group by index_type, status;
INDEX_TYPE STATUS COUNT(*)
--------------------------- -------- ----------
LOB VALID 51
NORMAL N/A 25
NORMAL VALID 479
CLUSTER VALID 11
下面来看看ROLLUP和CUBE语句的执行结果。
SQL> select index_type, status, count(*) from t group by rollup(index_type, status);
INDEX_TYPE STATUS COUNT(*)
--------------------------- -------- ----------
LOB VALID 51
LOB 51
NORMAL N/A 25
NORMAL VALID 479
NORMAL 504
CLUSTER VALID 11
CLUSTER 11
566
已选择8行。
SQL> select index_type, status, count(*) from t group by cube(index_type, status);
INDEX_TYPE STATUS COUNT(*)
--------------------------- -------- ----------
566
N/A 25
VALID 541
LOB 51
LOB VALID 51
NORMAL 504
NORMAL N/A 25
NORMAL VALID 479
CLUSTER 11
CLUSTER VALID 11
已选择10行。
查询结果不是很一目了然,下面通过Oracle提供的函数GROUPING来整理一下查询结果。
SQL> select grouping(index_type) g_ind, grouping(status) g_st, index_type, status, count(*)
2 from t group by rollup(index_type, status) order by 1, 2;
G_IND G_ST INDEX_TYPE STATUS COUNT(*)
---------- ---------- --------------------------- -------- ----------
0 0 LOB VALID 51
0 0 NORMAL N/A 25
0 0 NORMAL VALID 479
0 0 CLUSTER VALID 11
0 1 LOB 51
0 1 NORMAL 504
0 1 CLUSTER 11
1 1 566
已选择8行。
这个查询结果就直观多了,和不带ROLLUP语句的GROUP BY相比,ROLLUP增加了对INDEX_TYPE的GROUP BY统计和对所有记录的GROUP BY统计。
也就是说,如果是ROLLUP(A, B, C)的话,首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。
下面看看CUBE语句。
SQL> select grouping(index_type) g_ind, grouping(status) g_st, index_type, status, count(*)
2 from t group by cube(index_type, status) order by 1, 2;
G_IND G_ST INDEX_TYPE STATUS COUNT(*)
---------- ---------- --------------------------- -------- ----------
0 0 LOB VALID 51
0 0 NORMAL N/A 25
0 0 NORMAL VALID 479
0 0 CLUSTER VALID 11
0 1 LOB 51
0 1 NORMAL 504
0 1 CLUSTER 11
1 0 N/A 25
1 0 VALID 541
1 1 566
已选择10行。
和ROLLUP相比,CUBE又增加了对STATUS列的GROUP BY统计。
如果是GROUP BY CUBE(A, B, C),则首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP BY操作。
除了使用GROUPING函数,还可以使用GROUPING_ID来标识GROUP BY结果。
SQL> select grouping_id(index_type, status) g_ind, index_type, status, count(*)
2 from t group by rollup(index_type, status) order by 1;
G_IND INDEX_TYPE STATUS COUNT(*)
---------- --------------------------- -------- ----------
0 LOB VALID 51
0 NORMAL N/A 25
0 NORMAL VALID 479
0 CLUSTER VALID 11
1 LOB 51
1 NORMAL 504
1 CLUSTER 11
3 566
已选择8行。
SQL> select grouping_id(index_type, status) g_ind, index_type, status, count(*)
2 from t group by cube(index_type, status) order by 1;
G_IND INDEX_TYPE STATUS COUNT(*)
---------- --------------------------- -------- ----------
0 LOB VALID 51
0 NORMAL N/A 25
0 NORMAL VALID 479
0 CLUSTER VALID 11
1 LOB 51
1 NORMAL 504
1 CLUSTER 11
2 N/A 25
2 VALID 541
3 566
已选择10行。
grouping_id()可以美化效果:
select DECODE(GROUPING_ID(C1), 1, '合计', C1) D1,
DECODE(GROUPING_ID(C1, C2), 1, '小计', C2) D2,
DECODE(GROUPING_ID(C1, C2, C1 + C2), 1, '小计', C1 + C2) D3,
count(*),
GROUPING_ID(C1, C2, C1 + C2, C1 + 1, C2 + 1),
GROUPING_ID(C1)
from T2
group by rollup(C1, C2, C1 + C2, C1 + 1, C2 + 1);
===========================================================
1. 报表合计专用的 Rollup 函数
销售报表
广州 1 月 2000 元
广州 2 月 2500 元
广州 4500 元
深圳 1 月 1000 元
深圳 2 月 2000 元
深圳 3000 元
所有地区 7500 元
以往的查询 SQL:
Select area,month,sum(money) from SaleOrder group by area,month
然后广州,深圳的合计和所有地区合计都需要在程序里自行累计
1. 其实可以使用如下 SQL:
Select area,month,sum(total_sale) from SaleOrder group by rollup(area,month)
就能产生和报表一模一样的纪录
2. 如果 year 不想累加,可以写成
Select year,month,area,sum(total_sale) from SaleOrder group by year, rollup(month,area)
另外 Oracle 9i 还支持如下语法 :
Select year,month,area,sum(total_sale) from SaleOrder group by rollup((year,month),area)
3. 如果使用 Cube(area,month) 而不是 RollUp(area,month) ,除了获得每个地区的合计之外,还将获得每个月份的合计,在报表最后显示。
4.Grouping 让合计列更好读
RollUp 在显示广州合计时,月份列为 NULL ,但更好的做法应该是显示为 " 所有月份 "
Grouping 就是用来判断当前 Column 是否是一个合计列, 1 为 yes ,然后用 Decode 把它转为 " 所有月份 "
Select Decode(Grouping(area),1,' 所有地区 ',area) area, Decode(Grouping(month),1,' 所有月份 ',month), sum(money) From SaleOrder Group by RollUp(area,month);
2. 对多级层次查询的 start with.....connect by
比如人员组织 , 产品类别 ,Oracle 提供了很经典的方法
SELECT LEVEL, name, emp_id,manager_emp_id FROM employee START WITH manager_emp_id is null CONNECT BY PRIOR emp_id = manager_emp_id;
上面的语句 demo 了全部的应用 ,start with 指明从哪里开始遍历树 , 如果从根开始 , 那么它的 manager 应该是 Null, 如果从某个职员开始 , 可以写成 emp_id='11'
CONNECT BY 就是指明父子关系 , 注意 PRIOR 位置
另外还有一个 LEVEL 列 , 显示节点的层次
3. 更多报表 / 分析决策功能
3.1 分析功能的基本结构
分析功能 () over( partion 子句 ,order by 子句 , 窗口子句 )
概念上很难讲清楚 , 还是用例子说话比较好 .
3.2 Row_Number 和 Rank, DENSE_Rank
用于选出 Top 3 sales 这样的报表
当两个业务员可能有相同业绩时 , 就要使用 Rank 和 Dense_Rank
比如
金额 RowNum Rank Dense_Rank
张三 4000 元 1 1 1
李四 3000 元 2 2 2
钱五 2000 元 3 3 3
孙六 2000 元 4 3 3
丁七 1000 元 5 5 4
这时 , 应该把并列第三的钱五和孙六都选进去 , 所以用 Ranking 功能比 RowNumber 保险 . 至于 Desnse 还是 Ranking 就看具体情况了。
SELECT salesperson_id, SUM(tot_sales) sp_sales, RANK( ) OVER (ORDER BY SUM(tot_sales) DESC) sales_rank FROM orders GROUP BY salesperson_id
3.3 NTILE 把纪录平分成甲乙丙丁四等
比如我想取得前 25% 的纪录 , 或者把 25% 的纪录当作同一个 level 平等对待 , 把另 25% 当作另一个 Level 平等对待
SELECT cust_nbr, SUM(tot_sales) cust_sales, NTILE(4) OVER (ORDER BY SUM(tot_sales) DESC) sales_quartile FROM orders GROUP BY cust_nbr ORDER BY 3,2 DESC;
NTITLE(4) 把纪录以 SUM(tot_sales) 排序分成 4 份 .
3.4 辅助分析列和 Windows Function
报表除了基本事实数据外 , 总希望旁边多些全年总销量 , 到目前为止的累计销量 , 前后三个月的平均销量这样的列来参考 .
这种前后三个月的平均和到目前为止的累计销量就叫 windows function, 见下例
SELECT month, SUM(tot_sales) monthly_sales, SUM(SUM(tot_sales)) OVER (ORDER BY month ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) max_preceeding FROM orders GROUP BY month ORDER BY month;
SELECT month, SUM(tot_sales) monthly_sales, AVG(SUM(tot_sales)) OVER (ORDER BY month ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) rolling_avg FROM orders GROUP BY month ORDER BY month;
Windows Function 的关键就是 Windows 子句的几个取值
1 PRECEDING 之前的一条记录
1 FOLLOWING 之后的一条记录
UNBOUNDED PRECEDING 之前的所有记录
CURRENT ROW 当前纪录
4.SubQuery 总结
SubQuery 天天用了 , 理论上总结一下 .SubQuery 分三种
1.Noncorrelated 子查询 最普通的样式 .
2.Correlated Subqueries 把父查询的列拉到子查询里面去 , 头一回 cyt 教我的时候理解了半天 .
3.Inline View 也被当成最普通的样式用了 .
然后 Noncorrelated 子查询又有三种情况
1. 返回一行一列 where price < (select max(price) from goods )
2. 返回多行一列 where price>= ALL (select price from goods where type=2)
or where NOT price< ANY(select price from goods where type=2)
最常用的 IN 其实就是 =ANY()
3. 返回多行多列 一次返回多列当然就节省了查询时间
UPDATE monthly_orders SET (tot_orders, max_order_amt) = (SELECT COUNT(*), MAX(sale_price) FROM cust_order) DELETE FROM line_item WHERE (order_nbr, part_nbr) IN (SELECT order_nbr, part_nbr FROM cust_order c)
========================================
/*--------理解grouping sets
select a, b, c, sum( d ) from t
group by grouping sets ( a, b, c )
等效于
select * from (
select a, null, null, sum( d ) from t group by a
union all
select null, b, null, sum( d ) from t group by b
union all
select null, null, c, sum( d ) from t group by c
)
*/
发表评论
-
oracle根据外键名查关联的表
2010-10-17 09:35 12311、查找表的所有索引(包括索引名,类型,构成列): se ... -
对于'Consistent Gets',''Physical Reads'和'DB Block Gets'的理解和解释
2009-10-14 16:40 2412db block get s : number ... -
Oracle extent allocation: AUTOALLOCATE vs. UNIFORM
2009-10-10 13:07 2165Starting with Oracle 9i, DBAs c ... -
Oracle的物化视图
2009-09-15 13:17 1898create materialized view ... -
解决 'OraOLEDB.Oracle.1' provider is not registered
2009-04-02 11:00 14457解决方法如下: 到ORACLE_HOME目录,如c:\Ora ... -
项目管理
2009-02-06 11:39 01、已有功能的修改,都要先申请,申请的内容包括 a、改动原因: ... -
在Oracle9i中使用多种Block Size
2009-01-16 16:16 990来源:http://dev.21tx.com/2005/04 ... -
Oracle 存储层次体系
2009-01-16 15:36 967数据库由一个或者多个表空间(tablespace)构成。 一 ... -
Oracle分析函数over及开窗函数
2009-01-16 13:08 2598来源:http://www.365master.com/ma ... -
与对象权限有关的表与视图
2009-01-14 09:47 1304与对象权限有关的表与视图 DBA_TAB_PRIVS ... -
Storing settings for SQL*PLUS (login.sql and glogi
2009-01-13 16:33 982glogin.sql Whenever SQL*PLUS s ... -
autotrace 配置
2009-01-12 15:53 779Autotrace 的配置有很多种方法,下面是其中的 ... -
Oracle 常用命令
2009-01-12 15:17 909修改用户密码 alter user scott ident ... -
改变Oracle日期的输出格式
2009-01-09 12:45 1571查看数据库设置 select * from v$nl ... -
Oracle 语法之 OVER (PARTITION BY ..)
2008-12-31 12:34 1746Oracle 语法之 OVER (PARTITION BY . ... -
计算机改名后 ORACLE 监听不工作解决方法
2008-12-31 11:02 1795解决方法: 1. 修改 ...
相关推荐
### SQL语句中Group BY 和Rollup以及Cube用法 #### Group BY 子句 `GROUP BY`子句是SQL查询中的一个非常重要的部分,它用于将数据表中的行按照一个或多个列进行分组,使得可以对每个分组执行聚合函数(如SUM、...
SQL Server中的用法为group by colomn with [rollup|cube],首先要弄明白rollup 和cube,就要知道group by的用法,group by 为对列进行分组,只展现分组统计的值,而 rollup 为分层次展现,cube 为展现列中所有层次...
GROUP BY 子句(rollup, ...GROUP BY 语句用于基本的分组,GROUP BY ROLLUP 语句用于生成所有可能的分组结果,GROUP BY CUBE 语句用于生成所有可能的组合结果,GROUP BY GROUPING SETS 语句用于生成指定的分组结果。
而在GROUP BY的基础上,Oracle数据库提供了两种高级分组功能:ROLLUP和CUBE,它们允许我们更灵活地生成汇总数据。 1. ROLLUP(滚联回溯): ROLLUP是GROUP BY的一个扩展,它不仅返回每个单独的分组结果,还会生成...
综上所述,`ROLLUP`和`CUBE`是在Oracle数据库中进行多维数据分析的强大工具,它们可以帮助我们轻松地生成不同级别的汇总数据。同时,结合使用`GROUPING`和`GROUPING_ID`函数,可以让查询结果更易于理解和分析。这些...
`CUBE`和`ROLLUP`是`WITH`子句中的两个特殊运算符,它们主要用于多维度数据分析和聚合操作,通常在`GROUP BY`语句中配合使用。 1. **CUBE运算符**: `CUBE`生成的结果集包含了所有可能的子集,即所选列中值的所有...
然而,GROUP BY还可以与GROUPING、ROLLUP和CUBE运算符结合使用,以实现更复杂的多维度汇总功能。这些高级的汇总方法在数据分析和报表生成中非常有用,尤其是在处理大型数据集时。 GROUPING运算符主要用于识别汇总行...
在数据库查询语言中,`CUBE`和`ROLLUP`是两种非常重要的分组函数,它们主要用于复杂的数据汇总和分析。这两种函数可以帮助我们以多种方式对数据进行分组和聚合,从而更好地理解数据集中的模式和趋势。本文将详细介绍...
### Group By 后使用 Rollup 子句的理解与应用 #### 一、Rollup 子句的基本...通过这些例子可以看出,`ROLLUP` 和 `CUBE` 都能够提供更丰富的数据分组选项,但在具体应用场景中应根据实际需求选择合适的子句来使用。
在数据库管理领域,`ROLLUP` 是一种用于生成汇总数据的SQL构造,它在多级分组时非常有用,...在使用`ROLLUP` 时,理解其生成的`NULL` 值的含义以及如何结合其他SQL语句进行数据筛选和排序,是提高数据分析效率的关键。
在SQLSERVER中,有四种特殊的运算符用于处理和汇总数据:UNION、CUBE、ROLLUP和COMPUTE。这些运算符在数据查询和分析时非常有用,尤其在处理多个数据源合并、多维数据分析和自定义汇总计算时。 首先,我们来详细...
ROLLUP是一个用于生成汇总数据的SQL语句特性,它允许在GROUP BY子句中对数据进行多级别的分组和汇总。例如,在给定的数据集中,我们有`col_a`、`col_b`和`col_c`三个列。当使用`GROUP BY rollup(col_a, col_b)`时,...
Postgresql 支持 ROLLUP 语句,使用 ROLLUP 语句可以对表中的数据进行分组,并且可以对分组结果进行 weiter grouping。例如: ```sql SELECT * FROM test GROUP BY ROLLUP (A, B, C); ``` Cube 语句 Postgresql ...
分组统计可以分为多种类型,我们常用的有三个:Grouping Sets、Rollup 和 Cube。这三种类型都可以用来实现分组统计,但它们之间有所区别。 首先,我们来说说 Grouping Sets。Grouping Sets 是一种特殊的分组统计...
7. CUBE 或 ROLLUP 选项:应用 CUBE 或 ROLLUP 选项,为 vt5 生成超组,生成 vt6。 8. HAVING 筛选器:应用 HAVING 筛选器,生成 vt7。 9. SELECT 列表:将 vt7 中的在 SELECT 中出现的列筛选出来,生成 vt8。 10. ...
通过Grouping Sets,我们可以实现类似于ROLLUP和CUBE的效果,但更为灵活。ROLLUP会产生所有可能的子集,而CUBE则会生成所有可能的全排列。GROUPING SETS则允许我们指定具体想要的分组组合,因此在某些场景下更为实用...