前言
在前文 《数据库查询:解锁数据宝藏的魔法之钥》 中,我们探讨了数据库查询的基础知识和技巧。本篇文章将带您迈入更深的数据库查询领域,深入研究多表联查和子查询的奥秘。多表联查使您能够跨越不同数据表,将信息融合在一起,解锁更全面的数据视角。而子查询则是查询中的查询,为复杂数据问题提供了简洁而强大的解决方案。
我们将深入探讨如何使用JOIN语句进行多表联查,以及如何构建高效的子查询,以满足各种数据分析和报告的需求。无论您是数据库管理员、数据科学家还是应用开发者,本文都将为您提供深入的见解,帮助您更好地利用数据库查询工具,探索数据的更多层面。
多表联查
笛卡尔积
两张表在连接查询的时候,如果没有连接条件,那么会产生笛卡尔积(冗余数据)
代码语言:java复制select emp.*,dept.* from emp,dept
3.1 内连接
查询出来的数据一定满足链接的规则。
语法:
代码语言:java复制方言:select * from 表1 别名1,表2 别名2 where 别名1.xx=别名2.xx
标准:select * from 表1 别名1 inner join 表2 别名2 on 别名1.xx=别名2.xx
代码语言:java复制select e.*,d.* from emp e inner join dept d on e.deptno=d.deptno;
3.2 左外链接
因为内连接的查询结果,并不是所有的数据,而是满足规则的数据。
左外链接,右外连接是为了补充内连接的查询结果的。
左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能查询出来。左表中不满足条件的记录,右表部分都为NULL
语法:
代码语言:text复制select * from 表1 别名1 left [outer] join 表2 别名2 on 别名1.xx=别名2.xx
代码语言:text复制select * from emp e left outer join dept d on e.deptno=d.deptno;
select e.ename,e.deptno,d.dname from emp e left outer join dept d on e.deptno=d.deptno;
3.3 右外连接
右表记录无论是否满足条件都会查询出来,而左表只有满足条件才能查询出来。右表中不满足条件的记录,左表部分都为NULL
语法:
代码语言:text复制select * from 表1 别名1 right [outer] join 表2 别名2 on 别名1.xx=别名2.xx
代码语言:text复制mysql> select * from emp e right outer join dept d on e.deptno=d.deptno;
练习1:查询所有的部门,以及对应的员工信息。
代码语言:text复制SELECT
e.*, d.*
FROM
emp e
RIGHT JOIN dept d ON e.DEPTNO = d.DEPTNO
select d.DNAME,d.DEPTNO,e.DEPTNO,e.EMPNO,e.ENAME from dept d left join emp e on d.DEPTNO = e.DEPTNO;
练习2:查询每个员工的员工信息,工资等级。emp,salgrade
代码语言:text复制SELECT
e.*,s.*
FROM emp e
LEFT JOIN salgrade s
on e.SAL BETWEEN s.LOSAL and s.HISAL
练习3:查询每个员工的员工信息,部门名称,部门位置,工资等级
代码语言:text复制SELECT
e.*,d.DNAME,d.LOC,s.GRADE
FROM emp e
LEFT JOIN dept d
ON e.DEPTNO = d.DEPTNO
LEFT JOIN salgrade s
on e.SAL BETWEEN s.LOSAL and s.HISAL;
练习4:查询在部门在纽约的员工信息,部门名称,工资等级。
代码语言:text复制select
e.*,d.dname,d.LOC,s.grade
FROM emp e
left join dept d
on e.deptno = d.deptno
LEFT JOIN salgrade s
on e.sal BETWEEN s.LOSAL and s.hisal
where d.LOC = 'NEW YORK';
练习5:查询每个部门的人数,部门名称,部门编号。
代码语言:text复制SELECT e.DEPTNO,d.DNAME,count(*) from emp e
LEFT JOIN dept d ON e.DEPTNO = d.DEPTNO
group by e.DEPTNO,d.DNAME;
select t.*,d.DNAME
from (
SELECT e.DEPTNO,count(*) from emp e group by e.DEPTNO
) t
left join dept d
on t.DEPTNO = d.DEPTNO;
子查询
子查询:是指sql语句中包含另外一个select 语句。
子查询出现的位置:
代码语言:java复制from 后,作为表
where 后,作为条件
注意事项:
1,子查询必须在()里
2,在子查询中不能使用order by子句
3,子查询可以再嵌套子查询,最多不能超过255层
子查询:单行子查询,多行子查询
- 单行子查询 子查询的结果是单行数据 在where条件后,需要配合单行运算符:>,<,>=,<=,!=,=
- 多行子查询 子查询的结果是多行数据
1.查询比allen工资高的员工信息。
select * from emp where sal > (select sal from emp where ename='allen');
练习1:查询工资不是最高的,也不是最低的员工信息。
mysql> select * from emp where sal !=(select max(sal) from emp ) and sal !=(select min(sal) from emp);
练习2:不是销售部的员工信息
dname--->deptno
思路一:
select deptno from dept where dname='sales'
mysql> select * from emp where deptno != (select deptno from dept where dname='sales');
思路二:
select deptno from dept where dname !='sales';
mysql> select * from emp where deptno in(select deptno from dept where dname !='sales');
练习3:查询员工信息,要求工资高于部门编号为10的中的任意员工即可
思路一:
select min(sal) from emp where deptno=10; //
mysql> select * from emp where sal >(select min(sal) from emp where deptno=10);
练习4:查询员工信息,工资大于30部门的所有人
思路一:
mysql> select * from emp where sal >(select max(sal) from emp where deptno=30);
练习5:查询本公司工资最高的员工详细信息
select max(sal) from emp;
select * from emp e,dept d
where sal=(select max(sal) from emp) and e.deptno=d.deptno;
最后
本期结束咱们下次再见