0
点赞
收藏
分享

微信扫一扫

Oracle分组扩展函数的使用(主要增加小计及合计金额)


  1.     在oracle及其它数据库中通常使用group by 进行数据分组,oracle在group by 的基础上提供了一组分组的扩展函数,这组扩展函数主要用于增加小计及总计记录,主要包括用于group by 之后的rollup,cube,grouping sets,和用于查询列或having子句中的grouping(单列)标识如果该列值为空则返回值为1,grouping_id(多列)将会计算返回的结果值(我们将会在下面进行详细的讨论),group_id()标识是否有重复数据,下面我们首先创建一个测试表:

      create table test_group_table(

            t_year number,

           t_month number,

           quantity number

     );

     然后插入相应的测试数据:

       insert into test_group_table values(2012,1,29);

       insert into test_group_table values(2012,1,39);

       insert into test_group_table values(2012,2,11);

       insert into test_group_table values(2012,3,12);

       insert into test_group_table values(2013,1,10);

       insert into test_group_table values(2013,2,20);

       insert into test_group_table values(2013,3,30);

       insert into test_group_table values(2013,4,40);

    正常状态下,我们使用普通的group by 子句: select t_year,t_month, sum(quantity) qty from test_group_table group by t_year,t_month;得到的返回结果如下:

    2012 3 12
    2012 1 68
    2013 2 20
    2012 2 11
    2013 1 10
    2013 3 30
    2013 4 40

rollup(t_year,t_month),得到的结果如下:

2012   1    30
2012   2    43.5
2012   3    55.5
2012   4    20
2012         149
2013   1    808
2013         808
                  957

上面结果集中红色部分即是/根据年份(t_year)的小计及最后的所有数量的合计值.

如果我们使用cube分组函数时,执行分组sql(select t_year,t_month, sum(quantity) qty from test_group_table group bycube(t_year,t_month);)得到的结果如下:

        957
 1    838
 2    43.5
 3    55.5
 4     20
2012  149
2012 1 30
2012 2 43.5
2012 3 55.5
2012 4 20
2013  808
2013 1 808
上面的结果中红色部分即为cube结果比rollup多出来的针对月份(t_month)的合计数量值。

而使用grouping sets扩展分组函数时,即执行sql(select t_year,t_month, sum(quantity) qty from test_group_table group bygroupint  sets(t_year,t_month)),将返回的结果集为为:

       1   838
       2   43.5
       3   55.5
       4   20
 2013  808
 2012  149

该结果集比cube的结果集只有针对年份和针对月份的分组值,并且没有合部记录的合计值;

下面我们再说一下having及select 后面可以使用的grouping(单列)函数,grouping_id(多列),及group_id()的使用方法:

  •     grouping(单列)

rollup(t_year,t_month);返回的结果集为:

           2012   1    30           0    0
           2012   2    43.5        0    0
           2012   3    55.5        0    0
           2012   4    20           0     0
           2012       149           0     1
           2013   1    808         0     0
           2013   5    907.54   0     0
           2013       1715.54   0     1
                1864.54   1      1

通过上面的结果集我们可以看到最后一列是全部结果的合计值,因此年份和月份列均为空因此均返回了1,而第5行和第8行的小计行,因为年份不为空,但月份为空,因此grouping(t_year)返回了0,而grouping(t_month)返回了1,注意,如果t_year列本身值即为空,则grouping(t_year)仍然返回0;

rollup(t_year,t_month) having grouping(t_year) = 1 and grouping(t_month) = 1)将只返回:

                1864.54   1      1

      而如果执行select t_year,t_month, sum(quantity) qty,grouping(t_year),grouping(t_month) from test_group_table group by rollup(t_year,t_month) havinggrouping(t_year) = 0 and grouping(t_month) = 1

    则返回 的结果集为:

   2012       149           0     1
            2013       1715.54   0     1

    因此我们可以使用grouping(单列)来进行相关数据的过滤操作.

  • grouping_id(多列)

              grouping_id(多列)的使用方法基本与grouping(单列)类似,但grouping_id可以传入多列,如果转入一列的情况下,它的返回结果也是列值为空则返回1,否则返回0;但如果参数转入为多列,则其的计算方式如下,我们以grouping(t_year,t_month)为例说明:

             如果t_year,t_month列均为空则grouping_id(t_year,t_month)返回值为二进制的11,转为10进制为3;

                     t_year为空,t_month不为空则返回值为10,转为10进制为2;

                     t_year不为空,t_month为空,则返回值为01转为10进制为1;

  • group_id()不接收任何参数,如果返回结果集中有重复记录,则该值为重复次数,执行sql:
    SELECT T_YEAR,
           T_MONTH,
           sum(quantity),
           group_id()
      FROM TEST_REPORT_TABLE
      group by rollup(t_year,t_month),t_month;
    返回的结果集为: 
         2012 1 30 0
    2013 1 808 0
    2012 2 43.5 0
    2012 3 55.5 0
    2012 4 20 0
    2013 5 907.54 0
    2012 1 30 1
    2013 1 808 1
    2012 2 43.5 1
    2012 3 55.5 1
    2012 4 20 1
    2013 5 907.54 1
     1 838 0
     2 43.5 0
     3 55.5 0
     4 20 0
     5 907.54 0
    红色部分因为存在一次重复的记录,group_id()返回值为1
举报

相关推荐

0 条评论