oracle多表查询

oracle基础
oracle单行函数
oracle多表查询
oracle分组函数
oracle子查询

---------------- 多表查询 -----------------

-- 笛卡尔积错误 (原因就是没有加条件)
-- 查询员工表与部门表
-- 2889条
--会拿EMPLOYEES表(左表)中的每一条数据与DEPARTMENTS(右表)中的每一条数据匹配 即 107*27
SELECT EMPLOYEES.EMPLOYEE_ID,EMPLOYEES.LAST_NAME,DEPARTMENTS.DEPARTMENT_ID,DEPARTMENTS.DEPARTMENT_NAME
FROM EMPLOYEES ,DEPARTMENTS  
-- 2889
SELECT 107*27 FROM dual;
----------------------
-- 内连接 等值连接:
-- 内连接 :合并具有同一列的两个以上的表得行,结果集中不包含一个表与另一个表不匹配的行

--正确写法
-- 106条,有一条列为NULL所以包含在结果集中
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e,DEPARTMENTS  d 
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID


--连接n个表,至少需要n-1个连接条件
-- 查询公司员工的LAST_NAME,DEPARTMENT_ID,CITY
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME,l.CITY
FROM EMPLOYEES e,DEPARTMENTS  d, LOCATIONS l 
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID AND d.LOCATION_ID = l.LOCATION_ID


--内连接 非等值连接

-- 查询公司 每个员工的工资属于第几档工资
SELECT EMPLOYEE_ID,LAST_NAME,SALARY,GRADE_LEVEL
FROM EMPLOYEES e,JOB_GRADES j
WHERE SALARY BETWEEN LOWEST_SAL AND HIGHEST_SAL


-- 外连接
-- 两个表在连接过程汇总除了返回满足条件连接的行以外
-- * 还返回左(或右)表汇总不满足条件的行,这种连接称为(左或者右)外连接
-- 没有匹配的行时,结果表中的列为NULL,外连接的where子句条件类似于内部连接
-- * 但连接条件中没有匹配行的表得列后面要加外连接运算符,即用圆括号括起来的加号(+)
-- 例:
-- 107 条
-- 左外连接 (有员工,员工可能没部门)
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e,DEPARTMENTS  d 
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID(+)
-- 右外连接 (有部门,部门里面没有员工)
-- 122 条
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e,DEPARTMENTS  d 
WHERE e.DEPARTMENT_ID(+) = d.DEPARTMENT_ID

-- join on 方式 内连接
-- 两个表连接 106条记录
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e JOIN DEPARTMENTS d 
on e.DEPARTMENT_ID = d.DEPARTMENT_ID
-- 三个表连接 106条记录
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME,l.CITY
FROM EMPLOYEES e 
JOIN DEPARTMENTS d  ON e.DEPARTMENT_ID = d.DEPARTMENT_ID
JOIN LOCATIONS l    ON d.LOCATION_ID = l.LOCATION_ID

-- 左外连接 (有员工,员工可能没部门)107条记录
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e 
left outer join DEPARTMENTS d  ON e.DEPARTMENT_ID = d.DEPARTMENT_ID
-- 右外连接 (有部门,部门里面没有员工)122条记录
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e 
right outer join DEPARTMENTS d  ON e.DEPARTMENT_ID = d.DEPARTMENT_ID
-- 满外连接(左右连接的结果都想出来) 123条记录
SELECT e.EMPLOYEE_ID,e.LAST_NAME,d.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e 
full outer join DEPARTMENTS d  ON e.DEPARTMENT_ID = d.DEPARTMENT_ID



---------------------------
--自连接 
-- 查询员工'chen' 的mannage信息
-- 需要通过两条语句查询出结果,自连接可以一条sql查询出来
select MANAGER_ID 
FROM EMPLOYEES
WHERE LOWER(LAST_NAME) = 'chen'

SELECT LAST_NAME,SALARY,EMPLOYEE_ID,EMAIL
FROM EMPLOYEES
WHERE EMPLOYEE_ID = 108

-- 查询员工'chen' 的mannage信息
SELECT emp.LAST_NAME,manager.LAST_NAME,manager.SALARY,manager.EMAIL,manager.EMPLOYEE_ID
FROM EMPLOYEES emp, EMPLOYEES manager
WHERE emp.MANAGER_ID = manager.EMPLOYEE_ID AND LOWER(emp.LAST_NAME)  = 'chen'


-- 练习题

--查询出公司员工的 last_name, department_name, city

SELECT e.LAST_NAME,d.DEPARTMENT_NAME,l.CITY
FROM EMPLOYEES e 
left join DEPARTMENTS d on e.DEPARTMENT_ID = d.DEPARTMENT_ID
left join LOCATIONS l   on d.LOCATION_ID = l.LOCATION_ID


SELECT e.LAST_NAME,d.DEPARTMENT_NAME,l.CITY
FROM EMPLOYEES e , DEPARTMENTS d, LOCATIONS l 
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID(+) AND d.LOCATION_ID = l.LOCATION_ID(+)


/*

28. 查询出 last_name 为 'Chen' 的 manager 的信息. (员工的 manager_id 是某员工的 employee_id) 
	
	0). 例如: 老张的员工号为: "1001", 我的员工号为: "1002", 

            我的 manager_id 为 "1001" --- 我的 manager 是"老张" 

	1). 通过两条 sql 查询:

*/
SELECT MANAGER_ID
FROM EMPLOYEES
WHERE LOWER(LAST_NAME) = 'chen'

SELECT * 
FROM EMPLOYEES
WHERE EMPLOYEE_ID = '108'

-- 2). 通过一条 sql 查询(自连接):

SELECT em.LAST_NAME,ma.*
FROM EMPLOYEES em,EMPLOYEES ma
WHERE LOWER(em.LAST_NAME) = 'chen' and ma.EMPLOYEE_ID = em.MANAGER_ID

-- 3) 通过一条 sql 查询(子查询):
SELECT * 
FROM EMPLOYEES
WHERE EMPLOYEE_ID =  (SELECT MANAGER_ID
FROM EMPLOYEES
WHERE LOWER(LAST_NAME) = 'chen')

--29. 查询每个员工的 last_name 和 GRADE_LEVEL(在 JOB_GRADES 表中). ---- 非等值连接

SELECT e.LAST_NAME,j.GRADE_LEVEL
FROM EMPLOYEES e, JOB_GRADES j
WHERE e.SALARY BETWEEN j.LOWEST_SAL AND HIGHEST_SAL


SELECT e.LAST_NAME,j.GRADE_LEVEL
FROM EMPLOYEES e join JOB_GRADES j
on e.SALARY BETWEEN j.LOWEST_SAL AND HIGHEST_SAL

-- 30. 左外连接和右外连接

			select last_name, e.department_id, department_name
			from employees e, departments d
			where e.department_id = d.department_id(+)
			
			select last_name, d.department_id, department_name
			from employees e, departments d
			where e.department_id(+) = d.department_id
/*			
			理解 "(+)" 的位置: 以左外连接为例, 因为左表需要返回更多的记录,
			右表就需要 "加上" 更多的记录, 所以在右表的链接条件上加上 "(+)"
			
			注意: 1). 两边都加上 "(+)" 符号, 会发生语法错误!
			      2). 这种语法为 Oracle 所独有, 不能在其它数据库中使用.	

*/
-- 31. SQL 99 连接 Employees 表和 Departments 表

-- 缺点: 要求两个表中必须有一样的列名.
SELECT *
FROM EMPLOYEES join DEPARTMENTS
using(DEPARTMENT_ID)

SELECT * 
FROM EMPLOYEES e join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID

-- 三表连接
SELECT * 
FROM EMPLOYEES e 
join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID
join LOCATIONS l
on d.LOCATION_ID = l.LOCATION_ID


-- 32. SQL 99 的左外连接, 右外连接, 满外连接 (outer)可省略
-- 107条
SELECT * 
FROM EMPLOYEES e 
left join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID
-- 122条
SELECT * 
FROM EMPLOYEES e 
right join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID
-- 123条
SELECT * 
FROM EMPLOYEES e 
full join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID

-- 1.	显示所有员工的姓名,部门号和部门名称。
SELECT e.LAST_NAME , e.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e
left join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID


SELECT e.LAST_NAME , e.DEPARTMENT_ID,d.DEPARTMENT_NAME
FROM EMPLOYEES e,DEPARTMENTS d
WHERE e.DEPARTMENT_ID = d.DEPARTMENT_ID(+)


--2.	查询90号部门员工的job_id和90号部门的location_id

SELECT e.LAST_NAME,d.DEPARTMENT_ID,d.LOCATION_ID 
FROM EMPLOYEES e
left join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID
WHERE e.DEPARTMENT_ID = 90 


-- 3.	选择所有有奖金的员工的last_name , department_name , location_id , city

SELECT e.LAST_NAME,d.DEPARTMENT_NAME,l.LOCATION_ID,l.CITY
FROM EMPLOYEES e
left join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID
left join LOCATIONS l
on d.LOCATION_ID = l.LOCATION_ID
where e.COMMISSION_PCT is not null


--4.	选择city在Toronto工作的员工的 last_name , job_id , department_id , department_name 

SELECT e.LAST_NAME,e.JOB_ID,e.DEPARTMENT_ID,d.DEPARTMENT_NAME 
FROM EMPLOYEES e
left join DEPARTMENTS d
on e.DEPARTMENT_ID = d.DEPARTMENT_ID
left join LOCATIONS l
on d.LOCATION_ID = l.LOCATION_ID
WHERE l.CITY = 'Toronto'

-- 5.	选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式
/*
employees	Emp#	manager	Mgr#
kochhar	101	king	100
*/
SELECT em.LAST_NAME as "employees",em.EMPLOYEE_ID as "Emp#",ma.LAST_NAME as "manager",ma.EMPLOYEE_ID as "Mgr#"
FROM EMPLOYEES em,EMPLOYEES ma
WHERE em.MANAGER_ID = ma.EMPLOYEE_ID(+)




















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值