一、引言
上几篇关于多表查询的基本几个部分全部学习完了。
多表查询的基本类型的查询包括以下:
1、内连接(隐式内连接、显示内连接):... [INNER] JOIN ... ON 条件;)
2、外连接(左外连接、右外连接):...LEFT/RIGHT[OUTER] JOIN ... ON 条件;
3、自连接:表 A 别名 Ajoin表 A 别名 B ON 条件 ...;
4、联合查询:UNION(去重) / UNION ALL
5、子查询(标量子查询、列子查询、行子查询、表子查询)
下面将通过12个案例来关于多表查询操作的巩固。这篇博客只有5个案例,剩下的后面博客写。
二、案例
下面这些案例涵盖了内连接、外连接、自连接、子查询以及它们的整合使用。
打开 DataGrip 工具完成以下这些需求。
(0)数据准备(员工表 emp 、部门表 dept 、薪资等级表 salgrade)
员工表:emp
部门表:dept
薪资等级表:salgrade
(下面是创建表结构、插入数据)
sqlCREATE TABLE salgrade( grade INT COMMENT '薪资等级', losal INT COMMENT '该等级最低薪资', hisal INT COMMENT '该等级最高薪资' )COMMENT '薪资等级表'; INSERT INTO salgrade VALUES (1,0,3000); INSERT INTO salgrade VALUES (2,3001,5000); INSERT INTO salgrade VALUES (3,5001,8000); INSERT INTO salgrade VALUES (4,8001,10000); INSERT INTO salgrade VALUES (5,10001,15000); INSERT INTO salgrade VALUES (6,15001,20000); INSERT INTO salgrade VALUES (7,20001,25000); INSERT INTO salgrade VALUES (8,25001,30000);
涉及到的全部表的预览
(1)查询员工的姓名、年龄、职位、部门名称(隐式内连接)
用到隐式内连接,多张表用逗号隔开。要注意笛卡尔积的问题(消除无效查询)
sqlSELECT e.name,e.age,e.job,d.name FROM emp AS e,dept AS d WHERE (e.dept_id = d.id);
(2)查询年龄小于30岁的员工的姓名、年龄、职位、部门信息(显式内连接)
sqlSELECT e.name,e.age,e.job,d.name FROM emp AS e INNER JOIN dept AS d ON e.dept_id = d.id WHERE e.age < 30;
(3)查询拥有员工的部门ID、部门名称
(注意:这里在部门表中 "人事部" 是没有员工的)
1、先查询拥有部门id的员工中的部门信息,再去重复数据。
sqlSELECT dept.id,dept.name FROM emp,dept WHERE emp.dept_id=dept.id;
2、去除重复数据,就要用到一个关键字:distinct(DISTINCT)
sqlSELECT DISTINCT dept.id,dept.name FROM emp,dept WHERE emp.dept_id=dept.id;
(4)查询所有年龄大于40岁的员工,及其归属的部门名称。如果员工没有分配部门,也需要展示出来
这里注意:一看就要用到外连接(避免有些字段的 NULL 影响查询的结果)
sqlSELECT e.*,d.name FROM emp e LEFT OUTER JOIN dept d ON e.dept_id = d.id WHERE age >40;
也可以用昨天学的子查询(表子查询)
sqlSELECT e.*,d.name FROM (SELECT * FROM emp WHERE age>40) AS e LEFT JOIN dept AS d ON e.dept_id= d.id;
(5)查询所有员工的工资等级
涉及到两张表:员工表 emp,薪资等级表 salgrade
连接条件:salary 与 薪资的范围 losal 、hisal
(emp.salary >= salgrade.losal AND emp.salary <= salgrade.hisal )
sqlSELECT e.*,s.grade,s.losal as '最低工资' , s.hisal as '最高工资' FROM emp e ,salgrade s WHERE e.salary >= s.losal AND e.salary <= s.hisal;
对于这题还有一种SQL语句的写法。
(用 BETWEEN ... AND....)
sqlSELECT e.*,s.grade,s.losal as '最低工资' , s.hisal as '最高工资' FROM emp e ,salgrade s WHERE e.salary BETWEEN s.losal AND s.hisal;