欢迎来到我的维度空间:今天是 本博客所有文章系本人在学习过程中遇到好的资料直接转载过来、有时候没有贴源码、原文地址,请谅解。

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)),
posted @ 2013-07-24 17:40  胡博维  阅读(664)  评论(0编辑  收藏  举报