多表查询练习

我们看一下多表连接这一章的练习题,回顾我们刚才讲的知识点

1. 多表连接查询时, 若两个表有同名的列, 必须使用表的别名对列名进行引用, 否则出错!

查询的时候,如果两个表有同名的列,必须使用表的别名对列名进行引用,否则出错,你得告诉我是哪个表里的,

这个是一定需要指明的

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

	
	select last_name, department_name, city
	from departments d, employees e, locations l
	where d.department_id = e.department_id and d.location_id = l.location_id

涉及到了三个表,last_name是employees表的,department_name是departments表,city是locations表,

这个我们就不写了,这个我们也写了这个练习了,你看一眼,这是我们实现多表连接的,第一种方式,比较通用的,

直接from几个表,加上where连接条件,这个不加会有笛卡尔积的错误,你不加或者是少加,这个写了,这个and忘了,

仍然是有笛卡尔积的错误,下一个

3. 查询出 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' --返回的结果为 108
			
			select *
			from employees
			where employee_id = 108
			
	2). 通过一条 sql 查询(自连接):
			
			select m.*
			from employees e, employees m
			where e.manager_id = m.employee_id and e.last_name = 'Chen'		
			
	3). 通过一条 sql 查询(子查询):	
			
			select *
			from employees
			where employee_id = (
			                      select manager_id 
			                      from employees
			                      where last_name = 'Chen'
			                    )

查询last_name这个我们已经做过了,这里就不说了,这里我们会的,通过两条SQL语句,或者我们使用一条的话,

那就自连接,下边还有一个叫子查询,子查询我们放在第6节,来给大家讲,也是一个SQL语句就能够搞定了,我们到那

再给大家来说,先放一个引子

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

			select last_name, salary, grade_level, lowest_sal, highest_sal
			from employees e, job_grades j
			where e.salary >= j.lowest_sal and e.salary <= j.highest_sal

查询每一个员工的last_name,以及他的grade_level,我们以他作为一个典型的例题,说了一下非等值连接,

是什么意思,也就是连接条件是一个非等值的,就这样

5. 左外连接和右外连接

			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 所独有, 不能在其它数据库中使用.	

他两个肯定指的是外连接了,左外右外外连接,上面的都叫内连接,左外右外就是你返回员工左表或者右表,

不满足条件的行,就分别叫做左外或者右外,这个是左外还是右外,where e.department_id = d.department_id(+)

这个是左外吧,大家怎么来记忆,我们刚才从定义上来说,是输出左表中不满足条件的行,叫左外,说明左表中的行数多,

所以叫左外,左表中的行数多,就是意味着你在这个条件的时候,右边得多加上几个空行,给他补齐,一行得一行行对应,

右边不是得多补几个,所以在右边补加号,右边补加号的叫左外连接,左边补加号的叫右外连接,或者就像刚才那样记忆,

左边多就是左外,右边多就是右外,他只能实现左外或者右外,满外是不可以实现的,要实现满外,只能够用SQL99,SQL99

怎么来实现呢,左外叫left outer join,outer也可以省略,也可以加上,加上就写在left和join之间,left,right和full,

这是左外,右外,和全外,那么除此之外,SQL99的语法当中,还可以实现他自己,如何实现多表连接,叫join on,就是这种

方式大家是需要掌握的,两种方式,一种是这种方式,join什么on,一种是开头的这样,这一章就需要大家掌握这两个重点,

那么除此之外呢,作为了解的,join on说了,叫using,上面还有一个家里natural join,自然的一个连接,这个我们作为了解,

using也是作为一个了解,他们两个都有局限性,真正我们开发中去使用的就是join on,或者最上面这个,就这样,这个我们说完

以后,我们来看练习题
6. SQL 99 连接 Employees 表和 Departments 表
			1).
			select *
			from employees join departments
			using(department_id)
			
			缺点: 要求两个表中必须有一样的列名.
			
			2).
			select *
			from employees e join departments d
			on e.department_id = d.department_id
			
			3).多表连接
			select e.last_name, 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			     
			
7. SQL 99 的左外连接, 右外连接, 满外连接
			1).
			select last_name, department_name
			from employees e left outer join departments d
			on e.department_id = d.department_id
			
			2).
			select last_name, department_name
			from employees e right join departments d
			on e.department_id = d.department_id
			
			3).
			select last_name, department_name
			from employees e full join departments d
			on e.department_id = d.department_id	
多表查询

1.	显示所有员工的姓名,部门号和部门名称。
a)	select last_name,e.department_id,department_name
b)	from employees e,departments d
c)	where e.department_id = d.department_id(+)

方法二:
select last_name,e.department_id,department_name
from employees e left outer join departments d
on e.department_id = d.department_id

一个一个来,第一个,显示所有员工的姓名,部门号,和部门的名称,select 姓名last_name,部门号department_id,

部门名称department_name,这是我们比较典型的多表连接的问题,from,两种方式,我们先写第一种,employees e,

departments d,上面尤其是department_id,因为它两个表都有这一列,需要你显示的指明,他是在那个表中的,

你写e也行,也d也可以,务必加上过滤条件,e.department_id等于d.department_id,这就是我们实现了一个多表的

一个查询

select last_name,e.department_id,department_name from employees e,departments d where

e.department_id=d.department_id

这个就是我们实现了一个多表的查询


106条记录,内连接,你看,大家注意,所有员工你就他加上

select last_name,e.department_id,department_name from employees e,departments d

where e.department_id = d.department_id(+)

107个人,这是我们写的一种方式,希望大家掌握,那我们还讲了SQL99语法的方式,我们这里写方法二,

那么这个怎么写,还是查询这样几个信息,我在这直接改了,他join他,on,把加号去掉,你要是左外连接的话,

加上一个left outer

select last_name,e.department_id,department_name from employees e left outer join 

departments d on e.department_id=d.department_id

两种方式你都给他掌握,我们来看第二个题,

2.	查询90号部门员工的job_id和90号部门的location_id
a)	select distinct job_id,location_id
b)	from employees e left outer join departments d
c)	on e.department_id = d.department_id
d)	where d.department_id = 90

90号部门员工的job_id,和location_id,我们看一下这个,job_id是不是只在employees表里边,

location_id在departments表里边,所以我们是不是需要这两个表,好了,再来,select,他只查job_id,

和location_id,from employees e,这里你使用哪一种方式都可以,要是SQL99语法就是join departments,

on e.department_id等于d.department_id,同时呢,还有个条件90号部门,那就是d.department_id等于90,

90号部门,这个你用e也可以,有连接条件了,他的90号部门的信息,就这样,有的员工没有job_id,在90号部门

没有这个信息,那这个怎么办,那就给你加上一个left呗,保险起见

select job_id,location_id from employees e left join departments d on 

e.department_id=d.department_id where e.department_id=90


这三个,我发现后两个一样,后两个一样,这个公司有三个人,你要是想去重的话,加上一个distinct就Ok了

select distinct job_id,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 last_name,department_name,d.location_id,city
from employees e join departments d
on e.department_id = d.department_id
join locations l
on d.location_id = l.location_id
where e.commission_pct is not null

选择有奖金的员工,select,输出这四个信息,这个四个信息,我们看标点符号,要特别注意一下,我们都是在英文的格式

下的,中文的支持一定要给他改过来,from两种方式都行,假设我还是用SQL99语法,employees e join departments d,

on e.department_id=d.department_id,然后再join,locations l,on d.location_id=l.location_id,几个表之间的

连接条件你得熟悉一下,要不然你没法写了,然后看一下有没有不明确列的,location_id需要指明是d表还是l表,其他几个

不写也没事,所有有奖金的员工,这个是不是还没有加这个条件,加一个where,e.commission_pct is not null,有奖金的

这样几个信息

select last_name,department_name,d.location_id,city from employees e join departments d 

on e.department_id=d.department_id 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 last_name , job_id , e.department_id , department_name
from employees e ,departments d,locations l
where e.department_id = d.department_id and l.city = 'Toronto' and d.location_id = l.location_id

你如果仅仅看要输出的结果的话,仅仅涉及到了两个表,employees表和departments表,但是多了一个city,city只

存在于locations表,所以还是三个条件,select,然后from,我们换一种方式吧,employees e,逗号,departments d,

那你这里需要指明d的或者e的,都行,这不行,这还得有一个,locations l,条件是什么,要求你e的department_id

等于d的department_id,同时and,l的city要是Toronto,多伦多,加拿大的一个城市

select last_name,d.department_id,department_name from employees e,departments d,locations l

where e.department_id=d.department_id and l.city = 'Toronto'

最后你看一下是否有未明确的列,没有就OK

表或视图不存在,employees少个o

select last_name,d.deparment_id,department_name,city from employees e,departments d,

locations l where e.deparment_id=d.deparment_id and l.city = 'Toronto'

106条记录,看有没有问题,看看,显然不对是吧,是不是还要加上一个条件,否则会发生笛卡尔积的错误了,

d.location_id=l.location_id

select last_name,d.department_id,department_name,city from employees e,departments d,

locations l where e.department_id=d.department_id and d.location_id=.location_id

and l.city = 'Toronto'


我们是不是说了,你有三个表的话,如果他们做连接查询,至少得需要两个连接条件,我这里光写了一个,

所以这个千万不能丢,要加上,l.city=''是额外的一个连接条件,你再看结果

select e1.last_name "employees",e1.employee_id "Emp#",e2.last_name"Manger",e2.employee_id "Mgr#"
from employees e1,employees e2
where e1.manager_id = e2.employee_id(+)

员工的员工号以及管理者的姓名,员工号,他的员工号是他,他老板的员工号是他,他直接直属的一个管理者,

把所有的人都给输出出来,这是不是一个自连接,这是一个自连接,我们实现一下,select,他只是需要查询到

他的员工名,和他的id,select员工名,last_name,employee_id,后边还是一个last_name,employee_id,

from employees,这里我就不写什么叫员工,什么叫老板,第一个叫e1,employees e2,我让e1当做员工,e2当做

老板的表,前面都是e1,两个表加连接条件,e1.manager_id=e2.employee_id,这个题目我们写完了,但是这个别名

相当于,所以你给他改一改,last_name这里有一个别名,employees,id起的叫Emp#,Manager,Mgr#

select e1.last_name "employees",e1.employee_id "Emp#",e2.last_name "Manager",e2.employee_id "Mgr#"

from employees e1,employees e2 where e1.manager_id=e2.employee_id

我们运行一下结果看看


106条记录,把每一个人以及他的管理者给列出来,肯定有一个人没有管理者,有个人没有管理者,给他

输出出来的话,给他在这里整一个左外连接

select e1.last_name "employees",e1.employee_id "Emp#",e2.last_name "manager",e2.employee_id "Mgr#"

from employees e1,employees e2 where e1.manager_id=e2.employee_id(+)

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值