ORACLE 007 --5 group by 的用法及增强、高级子查询

在介绍GROUP BY 和 HAVING 子句前,我们必需先讲讲sql语言中一种特殊的函数:聚合函数,例如SUM, COUNT, MAX, AVG等。这些函数和其它函数的根本区别就是它们一般作用在多条记录上。

SELECT SUM(population) FROM bbc

  这里的SUM作用在所有返回记录的population字段上,结果就是该查询只返回一个结果,即所有国家的总人口数。

  通过使用GROUP BY 子句,可以让SUM 和 COUNT 这些函数对属于一组的数据起作用。当你指定 GROUP BY region 时,属于同一个region(地区)的一组数据将只能返回一行值,也就是说,表中所有除region(地区)外的字段,只能通过 SUM, COUNT等聚合函数运算后返回一个值。

  HAVING子句可以让我们筛选成组后的各组数据,WHERE子句在聚合前先筛选记录.也就是说作用在GROUP BY 子句和HAVING子句前.
而 HAVING子句在聚合后对组记录进行筛选。

  让我们还是通过具体的实例来理解GROUP BY 和 HAVING 子句,还采用第三节介绍的bbc表。

  SQL实例:

  一、显示每个地区的总人口数和总面积:

SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region

  先以region把返回记录分成多个组,这就是GROUP BY的字面含义。分完组后,然后用聚合函数对每组中的不同字段(一或多条记录)作运算。

  二、 显示每个地区的总人口数和总面积.仅显示那些面积超过1000000的地区。

SELECT region, SUM(population), SUM(area)
FROM bbc
GROUP BY region
HAVING SUM(area)>1000000

  在这里,我们不能用where来筛选超过1000000的地区,因为表中不存在这样一条记录。

  相反,HAVING子句可以让我们筛选成组后的各组数据.

group by 的增强、高级子查询、DML和DDL语句扩展

组函数
avg,sum,count,min,max
select id,sum(age) from users group by id having sum(age)>40;
超级聚合
rollup,cube
rollup从右往左再聚合
select id,num,sum(age) from users group by rollup(id,num)
cube从左往右取
select id,num,sum(age) from users group by cube(id,num)
grouping函数,返回的值,1肯定,0否定
select id,sum(age),grouping(id) from users;

grouping sets
分别求统计,再union
select id,num,sum(age) from users group by grouping sets((id),(num))
select id,num,sum(age) from users group by rollup((id,num));

select id,num,sum(age) from users group by id,rollup(num);

高级子查询
inner query ,outer query
select name from users where age >(select age from users where id =322);
成对的进行比较
select student_id,teacher_id,class_id from students
where (teacher_id,class_id) in (select teacher_id,class_id from students where student_id in (222,332))

在from中使用子查询,注意要加上别名
select a.id,a.name,b.type from students a,(select type from teachers) b where a.teacher_id=b.id;
标量子查询
精确的从一行中返回一列,独立的
关联子查询
循环的方式加以执行,内查询依赖于外查询
select name,age from users a
where age >(select avg(age) from users b where b.id=a.id )
exists,not exists
select * from students t1 where exists (select * from student_details t2 where t1.id=t2.id and t2.detail_id=22);
关联更新
用另外一张表更新当前表
update test1 t2 set age= (select age from test2 t2 where t1.id=t2.id)
关联删除
delete from test1 t1 where id in (select id from test2 t2 where t1.id=t2.id and age >20))
分层结构
select id,name from student start with id=292 connect by prior id=c_id;
select level,id,name from student start with id=292 connect by prior id=c_id;

DML和DDL语句扩展
DML:INSERT,DELETE,UPDATE
多表插入
无条件insert
有条件all insert
有条件first insert
选择insert
insert [all] [conditional_insert_clause]
[insert_into_clause values_clause] (subquery)
insert all into test1(id,name) values(id,name) into test2(id,address) values(id,address)
select id,name,address from test3 where id>23;
有条件的插入
insert all
when name like 't%' then
into test1(id,name) values(id,name)
when name like 'h%' then
into test2(id,address) values(id,address)
select id,name,address from test3 where id>23;
旋转插入
假设表sales_source_date的表结构为,employee_id,week_id,sales_mon,sales_tue,sales_wed,sales_thu,sales_fri
我想把这些记录保存在sales_info表中,表结构为employee_id,week,sales
insert all
into sales_info values (employee_id,week_id,sales_mon)
into sales_info values (employee_id,week_id,sales_tue)
into sales_info values (employee_id,week_id,sales_wed)
into sales_info values (employee_id,week_id,sales_thu)
into sales_info values (employee_id,week_id,sales_fri)
select employee_id,week_id,sales_mon,sales_tue,sales_wed,sales_thu,sales_fri from sales_source_date;
创建表时创建索引
create table test_index_table
(id int not null primary key using index(create index index1 on test_index_table(id)),
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值