《数据库查询大师:掌握SQL的终极技艺》

2023-09-27 23:24:02 浏览数 (1)

前言

在前文 《数据库查询:解锁数据宝藏的魔法之钥》 中,我们探讨了数据库查询的基础知识和技巧。本篇文章将带您迈入更深的数据库查询领域,深入研究多表联查和子查询的奥秘。多表联查使您能够跨越不同数据表,将信息融合在一起,解锁更全面的数据视角。而子查询则是查询中的查询,为复杂数据问题提供了简洁而强大的解决方案。

我们将深入探讨如何使用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层

子查询:单行子查询,多行子查询

  1. 单行子查询 子查询的结果是单行数据 在where条件后,需要配合单行运算符:>,<,>=,<=,!=,=
  2. 多行子查询 子查询的结果是多行数据

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;

输入图片说明输入图片说明

最后

本期结束咱们下次再见

0 人点赞