下章:Oracle入门(十三C)之高级查询(下)
一、多表格查询
(1)定义
将两个或两个以上的表格,按照一定的关系连接起来进行查询。
(2)多表格查询分类
- 连接查询
- 嵌套查询
- 集合查询
二、连接查询
(1)内连接查询
查询城市及其省份名称,显示对应国家
SQL 99 :
select city,state_province, country_name
from locations L join countries C
on L.country_id = C.country_id;
oracle:
select city,state_province, country_name
from locations L, countries C
where L.country_id =C.country_id;
查询雇员信息,显示其相关的工作名称
SQL 99 :
select first_name, job_title
from employees E join jobs J
on E.job_id = J.job_id;
注意:内连接查询中,对连接条件进行匹配,只列出符合条件的数据,如果要显示完全,则应该使用外联接
(2)左外连接查询
要求显示全部雇员名称及其所在部门名称,如果没有对应的部门名称便以null显示
SQL 99 :
select last_name, department_name
from employees E Left join departments D
on E.department_id = D.department_id;
oracle:
select last_name, department_name
from employees E, departments D
where E.department_id = D.department_id(+);
(3)右外连接查询
要求显示全部部门名称及其包含雇员名称,如果没有对应的雇员名称便以null显示
SQL 99 :
select last_name, department_name
from employees E Right join departments D
on E.department_id = D.department_id;
oracle:
select last_name, department_name
from employees E,departments D
where E.department_id(+) = D.department_id;
(4)全外连接查询
要求显示全部的雇员和部门名称
SQL 99 :
select last_name, department_name
from employees E full join departments D
on E.department_id = D.department_id
order by last_name;
(5)自然连接
当具有相同列名且数据类型也相同的情况下,自动连接,相当于内连接的等值连接
NATURAL:
select first_name, job_title
from employees E
natural join jobs J;
等值连接 :
select first_name, job_title
from employees E join jobs J
on E.job_id = J.job_id;
(6)Using子句
如果数据类型和名称相同的情况下,使用using子句指定列名,如果列名称不相同的情况下,使用on子句
using子句:
select first_name, job_title
from employees E join jobs J
using (job_id);
on子句:
select name, class_title
from student S join class C
On S.classID = C.cid ;
(7)交叉连接
笛卡尔积,没有连接条件
SQL 99 :
Select pmid, sname, pdate, pstate
From procure P CROSS join supplier S;
oracle:
Select pmid, sname, pdate, pstate
From procure P, supplier S;
三个以上的表查询
Select omid, gname, gtname, oprice, onum
From t_order_items join t_goods using(gid) join t_gtype using(gtid);
三、分组计算
如果了解就读年级学生的平均身高?
需要编写多个不同的SQL 语句才能实现此目的:
- SELECT AVG(身高) FROM 学生WHERE 就读年级= 2013;
- SELECT AVG(身高) FROM 学生WHERE 就读年级= 2014;
- SELECT AVG(身高) FROM 学生WHERE 就读年级= 2015;
需要编写上述一系列语句。要简化此类问题,只使用一个语句就达到相同的目的,可使用GROUP BY 与HAVING 子句。
SELECT AVG(身高) FROM 学生
GROUP BY 就读年级;
(1)根据公司部门分组,统计各部门每月人力总成本
select department_id,sum(salary)
from employees
group by department_id
order by department_id;
(2)带where条件的分组计算:统计2005年及其以后入职各部门员每月工人力成本
select department_id,sum(salary)
from employees
where extract(year from hire_date)>= 2005
group by department_id
order by department_id;
(3)带where条件的分组计算:统计部门高收入员工【月薪收入超过10000】的人数
Select department_id,count(*)
From employees
Where salary > 10000
Group by department_id
Order by department_id;
(4)带分组以后的条件计算:统计部门员工月薪收入超过10000以上,并且数量超过2人的部门
Select department_id,count(*)
From employees
Where salary > 10000
having count(*)>2
Group by department_id
Order by department_id;
(5)分组计算的连接查询:统计采购数量在10以上的采购次数在2次以上的商品采购次数信息,并且显示商品名称信息
Select gid,gname,count(gid)
From t_procure_items
join t_goods using(gid)
Where pinum>10
Group by gid,gname
Having count(gid)>2;
注意:GROUP BY组函数要求,SELECT子句中列出的任何不属于组函数的列,都必须在GROUP BY 子句中列出。