Oracle之Group By

前几天把《Oracle SQL高级编程》看完了,受益匪浅。近期抽空写些总结

以下内容这里另一位作者写的很简练http://www.2cto.com/database/201204/126721.html

准备实验数据

create table sales_log(
category varchar2(10),
year varchar2(4),
month varchar2(2),
sales number
);

declare 
  type categorys_varray is varray(3) of varchar2(10);
  v_categorys categorys_varray := categorys_varray('Apple', 'Orange', 'Banana');
  type years_varray is varray(3) of varchar2(4);
  v_years years_varray := years_varray('2011', '2012', '2013');
  type months_varray is varray(12) of varchar2(2);
  v_months months_varray := months_varray('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12');
  v_sales number;  
begin 
  for i in 1..v_categorys.count loop
    for j in 1..v_years.count loop
      for k in 1..v_months.count loop
        SELECT TRUNC(100+900*dbms_random.value) into v_sales FROM dual;
        insert into sales_log(category, year, month, sales) values(v_categorys(i), v_years(j), v_months(k), v_sales);
      end loop;
    end loop;
  end loop;
  commit;
end;


一、group by基本用法:

1)计算每年的总销售额

select year, sum(sales) from sales_log group by year;

2)各类水果在各年的销售额

select year, category, sum(sales) from sales_log group by year, category;



在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚组函数
如果想对分组结果进行排序,必须手动指定order by

Oracle之Group By_第1张图片

二、having

1)查出2013年销售额在1w以上的水果

select category, sum(sales) 
from sales_log 
where year = '2013' 
group by category 
having sum(sales) > 7000;
where是针对原数据进行筛选,而having子句只是针对汇总后的结果进行筛选

三、cube

1)统计每种水果每年的销售额、每种水果所有销售额、每年销售额、全部销售额

select category, year, sum(sales)
from sales_log
group by cube(category, year)
order by category, year nulls last;
categroy,year分组合计
category分组合计
year分组合计
总计

Oracle之Group By_第2张图片    

四、grouping (只用于rollup和cube)

1)对上面结果的空值进行处理,'ALL YEAR'代替NULL表示所有年份,以'ALL CATEGORY'代表所有种类

select decode(grouping(category), 1, 'ALL CATEGORY', category), decode(grouping(year), 1, 'ALL YEAR', year), sum(sales)
from sales_log
group by cube(category, year)
order by category, year;

Oracle之Group By_第3张图片

2) 统计每种水果每年的销售额、每种水果所有销售额、每年销售额、全部销售额

select decode(grouping(category), 1, 'ALL CATEGORY', category), year, sum(sales)
from sales_log
group by cube(category, year)
having grouping(year) != 1 
order by category, year;

使记录含义更清晰,而不是单纯的一个null值。

Oracle之Group By_第4张图片

五、grouping_id (since 9i)

1)分别对"每种水果每年的销售额"、"每种水果所有销售额"、"每年销售额"、"全部销售额"进行分类标识

select grouping_id(category, year), decode(grouping(category), 1, 'ALL CATEGORY', category), decode(grouping(year), 1, 'ALL YEAR', year), sum(sales)
from sales_log
group by cube(category, year)
order by category, year;
是grouping()的扩展,相当于grouping_id(category,year)=(grouping(category) || grouping(year)表示的二进制)的值

结果分为三类

Oracle之Group By_第5张图片

六、group_id() 刚认识这个函数,待进一步测试

select group_id(), grouping_id(category, year), decode(grouping(category), 1, 'ALL CATEGORY', category), decode(grouping(year), 1, 'ALL YEAR', year), sum(sales)
from sales_log
group by cube(category, year)
order by category, year;
group_id()函数,无参数,可以表示此分组记录是否重复,0表示第一次,1表示重复。

七、grouping sets

1)统计每种水果每年的销售额、每种水果所有销售额、每年销售额、全部销售额

select category, year, sum(sales)
from sales_log
group by grouping sets((category, year), (category), (year), ())

分别以按(category,year)和(category)以及(year)的作为group by的条件分组

Oracle之Group By_第6张图片

八、rollup ( 可以和cube对比一下)

1)统计全年销售额、每种水果每年销售额

select year, category, sum(sales)
from sales_log
group by rollup(year, category);
category,year分组合计
category分组合计
总计
Oracle之Group By_第7张图片





你可能感兴趣的:(oracle,cube,grouping,rollup,grouping,by,group,grouping_id,sets,group_id)