度量快速开发平台-专业、快速的软件定制快开平台

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 部件 流程 SQL
查看: 2970|回复: 8
打印 上一主题 下一主题

[分享] ORACLE 高级函数应用一

[复制链接]

542

主题

5916

帖子

1万

积分

作者

Rank: 7Rank: 7Rank: 7

积分
13589
跳转到指定楼层
楼主
发表于 2020-6-30 14:07:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
--分组函数
1、ROLLUP
--统计标准分组及相应维度的小计、合计
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()可以美化效果:

CALL VPD_PKG.SET_CONTEXT_COMPID('-1');
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'),COUNT(*)
    FROM XTBILL2011 A
    GROUP BY ROLLUP(A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'));
--2)部分rollup分组
--对标准分组后,对a.typeid进行小计
SELECT A.DWDH,A.YEAR,A.TYPEID,COUNT(*)
    FROM XTYWBILL A
    GROUP BY A.DWDH,A.YEAR,ROLLUP(A.TYPEID);
2、CUBE
--rollup只能对“从右到左递减”,如需要全方位的维度进行统计,需要用到cube函数
--1)
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'),COUNT(*)
    FROM XTBILL2011 A
    GROUP BY CUBE(A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'));
--2) 部分cube:可以去掉合计与某些不需要的小计。
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'),COUNT(*)
    FROM XTBILL2011 A
    GROUP BY A.VPD_COMPID,CUBE(TO_CHAR(A.TTIME,'MM'));
   
3、GROUPING SETS
--说明:仅关注单列分组,某些维度的小计
--group by grouping sets(a,b,c)相当于group by a,group by b,group by c
--这三组的union all结果
--1)
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'),COUNT(*)
    FROM XTBILL2011 A
    GROUP BY GROUPING SETS(A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'));
--2)部分grouping sets分组
--在group by的基础上进行小计,仅关注小计的情况
SELECT A.DWDH,A.YEAR,A.TYPEID,COUNT(*)
    FROM XTYWBILL A
    GROUP BY A.DWDH,GROUPING SETS(A.YEAR,A.TYPEID);
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'),COUNT(*)
    FROM XTBILL2011 A
    GROUP BY A.VPD_COMPID,GROUPING SETS(TO_CHAR(A.TTIME,'MM'));
4、CUBE,ROLLUP作为GROUPING SETS的参数
--grouping sets操作只对单列进行分组,而不提供合计的功能,如果需要grouping sets提供合计的功能,
--那么可以使用rollup或cube作为grouping sets的参数,比如下面的语句提供合计功能:
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM') AS TTIME,COUNT(*)
    FROM XTBILL2011 A
    GROUP BY GROUPING SETS(ROLLUP(A.VPD_COMPID),ROLLUP(TO_CHAR(A.TTIME,'MM')));
--这条语句产生了两个合计行,因为rollup或cube作为grouping sets的参数,相当于对每个
--rollup与cube操作的union all。所以上面的语句等价于:
SELECT A.VPD_COMPID,NULL AS TTIME,COUNT(*)
    FROM XTBILL2011 A
    GROUP BY ROLLUP(A.VPD_COMPID)
UNION ALL
SELECT NULL,TO_CHAR(A.TTIME,'MM'),COUNT(*)
    FROM XTBILL2011 A
    GROUP BY ROLLUP(TO_CHAR(A.TTIME,'MM'));
   
5、组合列分组简介:
--分组方式: rollup(a,b,c)<=>group by a,b,c; group by a,b; group by null
--分组方式: rollup(a,(b,c))<=>group by a,b,c; group by a; group by null
--分组方式: rollup(a,b),rollup(c)<=>group by a,b,c; group by a,b; group by a,c; group by a; group by c; group by null
--分组方式: rollup(a,b),grouping sets(c)<=>group by a,b,c; group by a,c; group by c
--分组方式: rollup(a),rollup(b),rollup(c)<=>group by a; group by b; group by c; group by a,b; group by a,c; group by b,c; group by a,b,c; group by null
6、GROUPING函数
--为了区别哪些是小计,grouping函数派上用场了!
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'),COUNT(*),GROUPING(A.VPD_COMPID),GROUPING(TO_CHAR(A.TTIME,'MM')),
    DECODE(GROUPING(A.VPD_COMPID),1,'所有单位',A.VPD_COMPID) VPD_COMPID,
    DECODE(TO_CHAR(A.TTIME,'MM'),1,'所有月份',TO_CHAR(A.TTIME,'MM')) TTIME   
    FROM XTBILL2011 A
    GROUP BY ROLLUP(A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'));
--过滤某些分组结果
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'),COUNT(*),GROUPING(A.VPD_COMPID),GROUPING(TO_CHAR(A.TTIME,'MM')),
    DECODE(GROUPING(A.VPD_COMPID),1,'所有单位',A.VPD_COMPID) VPD_COMPID,
    DECODE(TO_CHAR(A.TTIME,'MM'),1,'所有月份',TO_CHAR(A.TTIME,'MM')) TTIME   
    FROM XTBILL2011 A
    GROUP BY ROLLUP(A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'))
    HAVING GROUPING(A.VPD_COMPID)=1 OR GROUPING(TO_CHAR(A.TTIME,'MM'))=0;
7、GROUPING_ID函数
--可用rollup或cube与grouping_id组合运用,过滤出想要的分组统计信息
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'),GROUPING_ID(A.VPD_COMPID,TO_CHAR(A.TTIME,'MM')),COUNT(*)
    FROM XTBILL2011 A
    GROUP BY CUBE(A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'))
    HAVING GROUPING_ID(A.VPD_COMPID,TO_CHAR(A.TTIME,'MM'))=2;  --1,2,3,0
--GROUPING_ID(a,b,c)过滤分组结果
分组级别   位向量    GROUPING_ID结果
a,b,C      0 0 0     0
a,B        0 0 1     1
A          0 1 1     3
汇总       1 1 1     7
8、GROUP_ID函数
--判断重复的分组
SELECT A.VPD_COMPID,TO_CHAR(A.TTIME,'MM') AS TTIME,GROUP_ID() ID,COUNT(*)
    FROM XTBILL2011 A
    GROUP BY GROUPING SETS(ROLLUP(A.VPD_COMPID),ROLLUP(TO_CHAR(A.TTIME,'MM')))
   -- HAVING GROUP_ID()=0;
   
9、实例应用说明:
DROP TABLE T;
CREATE TABLE t(
   ORDER_DATE DATE,  --订购日期
   ORDER_NO   NUMBER,  --订购号
   ORDER_BOOK  VARCHAR2(10),  --订购书籍
   ORDER_FEE   NUMBER,  --订单总金额
   ORDER_NUM   NUMBER
);
INSERT INTO T
   SELECT TO_DATE('2010-05-01','YYYY-MM-DD')+LEVEL,
   TRUNC(DBMS_RANDOM.value*1000),
   'book1',100+LEVEL,LEVEL
   FROM DUAL
   CONNECT BY LEVEL<5;
INSERT INTO T
   SELECT TO_DATE('2010-06-01','YYYY-MM-DD')+LEVEL,
   TRUNC(DBMS_RANDOM.value*1000),
   'book2',200+LEVEL,LEVEL
   FROM DUAL
   CONNECT BY LEVEL<5;
--要求:每组order_book内,按日期升序排列(order_no排序不管),常规分组在前,小计在后,合计最后。
SELECT DECODE(GROUPING_ID(ORDER_DATE,ORDER_NO,ORDER_BOOK),6,ORDER_BOOK||'小计',
   7,'合计',
   TO_CHAR(ORDER_DATE,'YYYY-MM-DD')
   ) ORDER_DATE1,
   ORDER_NO,
   DECODE(GROUPING_ID(ORDER_DATE,ORDER_NO,ORDER_BOOK),6,NULL,ORDER_BOOK) ORDER_BOOK1,
   SUM(ORDER_FEE) ORDER_FEE,
   SUM(ORDER_NUM) ORDER_NUM
  FROM T
  GROUP BY ROLLUP(ORDER_BOOK,(ORDER_DATE,ORDER_NO))
  ORDER BY ORDER_BOOK,ORDER_DATE;
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

542

主题

5916

帖子

1万

积分

作者

Rank: 7Rank: 7Rank: 7

积分
13589
沙发
 楼主| 发表于 2020-6-30 14:08:15 | 只看该作者
回复 支持 反对

使用道具 举报

235

主题

2547

帖子

5834

积分

论坛元老

Rank: 8Rank: 8

积分
5834
板凳
发表于 2020-6-30 14:51:35 | 只看该作者
回复

使用道具 举报

141

主题

1551

帖子

3573

积分

论坛元老

Rank: 8Rank: 8

积分
3573
地板
发表于 2020-6-30 17:17:03 | 只看该作者
回复 支持 反对

使用道具 举报

542

主题

5916

帖子

1万

积分

作者

Rank: 7Rank: 7Rank: 7

积分
13589
5#
 楼主| 发表于 2020-6-30 14:21:44 | 只看该作者
回复 支持 反对

使用道具 举报

141

主题

1551

帖子

3573

积分

论坛元老

Rank: 8Rank: 8

积分
3573
6#
发表于 2020-6-30 17:47:29 | 只看该作者

点评

爱卿既已阅读,明日将阅后感上奏  详情 回复 发表于 2020-7-1 14:15
回复 支持 反对

使用道具 举报

542

主题

5916

帖子

1万

积分

作者

Rank: 7Rank: 7Rank: 7

积分
13589
7#
 楼主| 发表于 2020-7-1 14:15:00 | 只看该作者

爱卿既已阅读,明日将阅后感上奏
回复 支持 反对

使用道具 举报

141

主题

1551

帖子

3573

积分

论坛元老

Rank: 8Rank: 8

积分
3573
8#
发表于 2020-7-1 14:45:06 | 只看该作者
回复 支持 反对

使用道具 举报

542

主题

5916

帖子

1万

积分

作者

Rank: 7Rank: 7Rank: 7

积分
13589
9#
 楼主| 发表于 2020-7-4 15:45:58 | 只看该作者
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|重庆度量科技  本站关键词:快速开发平台

GMT+8, 2024-4-28 09:17 , Processed in 0.146119 second(s), 25 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表