1.基本查询
使用scott案列
----来源csdn:
Mysql下-scott用户表的创建_风泊月mysql 员工表-CSDN博客

案列1:查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大小的J
查询雇员,从emp表中查询,sal>500 or job=='MANAGER'表示查询工资高于500或岗位为MANAGER, ename like 'J%'表示查询ename为J开头。

也可以使用函数进行截取ename来进行判断:
substring(ename,1,1)='J';

案例2:将雇员按部门号升序而工资降序进行排序:
----表示将相同部门号的雇员按工资,以降序排列
order by deptno asc,sal desc;

不显示其他信息:

案例3:按年薪降序进行排序
年薪等于sal*12+comm comm为奖金
按年薪排:

加上奖金(comm可为null,当comm为null时,不能参加运算)
ifnull(comm,0)表示comm若为null就取0,若不为null就取comm

案例4:显示工资最高的员工的名字和工作岗位:
显示一个最高:

但是可能有多个员工工资都为最高工资:
通过子查询和聚合函数进行查找
先通过子查询select max(sal) from emp找到最高工资,再交给where进行筛选:
select ename,job from emp where sal=(select max(sal) from emp);

案例4:显示工资高于平均工资的员工名和工资
同样通过select子句找出平均工资,再交给where进行筛选:
select ename,sal from emp where sal>(select avg(sal) from emp);

案例5:显示每个部门的平均工资和最高工资,只显示整数部分
通过format进行格式化
通过将每个部门分组(group by)再寻找平均工资和最高工资

案例6:显示平均工资低于2000的部门号和它的平均工资:
先算每个部门的平均工资:

再通过having对聚合函数处理的数据进行筛选:
select deptno avg(sal) 平均工资 from emp group by deptno having 平均工资>2000;

案例7:显示每种岗位的雇员总数,平均工资
先算每种岗位的员工总数:
select count(*) from emp group by job;
再算平均工资:
select count(*),avg(sal) from emp group by job;
再优化显示:
select job 岗位,count(*) 岗位员工总数,format(avg(sal),0) 岗位平均工资 from emp group by job;

2.多表查询
实际开发中数据往往来自不同的表,所以需要多表查询。
同样引用
Mysql下-scott用户表的创建_风泊月mysql 员工表-CSDN博客
来源的soctt数据库进行演示:
案例1:显示雇员名,工资和部门名
其中的部门名不属于员工表,而是部门表,需要从两张表进行整合:
先拿到两张表的全部数据:select * from emp,dept;

发现是将emp表中的一个数据与dept表中的所有数据进行穷举:


每一个emp表中的数据都会与dept表中的所有数据进行组合。
------称为两张表中的笛卡尔积,将两张表中的所有数据都进行了组合。
但是一个emp表中的数据只有一个dept表中的数据对它有意义,所以要将对它没用的数据筛选出去:
select * from emp,dept where emp.deptno=dept.deptno;
只显示有意义的数据:

再筛选出要求打印的员工名,工资,部门名:
select ename,sel,dname from emp,dept where emp.deptno=dept.deptno;

案例2:显示部门号为10的部门名,员工名和工资

3.自连接
自连接时指在同一张表连接查询-----对一张表中的数据做笛卡尔积
如:
dept表:

将同一张表中的数据进行笛卡尔积,因为表名不能重复出现,所以用as进行重命名:
select * from dept as t1,dept as t2;


案例1:显示员工CLARK的上级领导的编号和姓名---mgr是上级编号,同时也是上级的empno
先在员工表中找CLARK的领导的编号:select mgr from emp where ename='CLARK';

再在员工表中找编号为7839的员工姓名:
select enam from emp where empno=7839;

就找到了CLARK的领导姓名
通过子查询来一条sql实现:
select ename,empno where empno=(select mgr from emp where ename='CLARK');

或通过自连接实现一条sql语句实现:
先做笛卡尔积,再筛选出员工CLARK与同一张表中所有员工组合的数据:
select * from emp e1,emp e2 where e1.ename='CLARK';

再筛选出与e1表中的CLARK的mgr编号对应的empno编号
select * from emp e1,emp e2 where e1.ename='CLARK' and e1.mgr=e2.empno;

再优化,仅打印领导编号和姓名:
select e2.empno,e2.ename from emp e1,emp e2 where e1.ename='CLARK' and e1.mgr=e2.empno;

4.子查询
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询
select 和子查询后的表结构都能进行笛卡尔积
4.1单行子查询
返回一行记录的子查询---子查询返回的结果是单列单行的
案例:显示和KING同一部门的员工

4.2多行子查询
返回多行记录的子查询----子查询返回的结果是多行单列的
4.2.1 in关键字使用,in是用来判断列值是否在某一个集合当中。
此处用于筛选是否在多行子查询返回的集合当中。
案例:查询和10号部门的员工的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包括10号部门本身的员工。
先找出10号部门员工去重后的工作岗位:

再找出与这些工作岗位相同的员工的名字,岗位,工资,部门号:
用in判断是否在子查询集合当中

再去除10号部门的员工本身。
用deptno <> 10 来表示deptno不等于10

4.2.2 all关键字----与子查询返回的所有行进行比较
any关键字---与子查询返回的任意一行进行比较,只要有一个为真,就为真
案例:显示工资比部门号为30号的所有员工的工资都高的员工的姓名,工资和部门号
先拿到30号部门的员工最高工资:
select max(sal) from emp where deptno=30;

再筛选工资高于30部门最高工资的员工的姓名,工资和部门号:
select ename ,sal,deptno from emp where sal>(select max(sal) from emp where deptno=30);

也可以通过多行子查询进行筛选:
先拿到30号部门所有人的工资:
select distinct sal from emp where demptno=30;

再找出比30号部门所有人工资都高的员工---通过all将数据与子查询返回的所有数据进行比较。
select ename,sal,deptno from emp where sal > all(select distinct sal from emp where deptno=30);

通过any语句找出比30号部门任意一员工工资高的员工,30号部门员工除外:
select ename,sal,deptno from emp where sal> any(select distinct sal from emp where deptno=30) and deptno <> 30;

4.3多列子查询
单行子查询是指子查询指返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询是指查询多个列数据的子查询语句。
案列:查询和ALLEN员工的部门和岗位完全相同的员工,不包含ALLEN自身
先拿到ALLEN的部门和岗位:
select deptno,job from emp where ename='ALLEN';

包含两列信息
再查找与这两列信息都相同的员工
select * from emp where (deptno,job)=(select deptno,job from emp where ename='ALLEN');

再去除ALLEN自身:and ename <>'ALLEN';

也可以通过in,all,any进行多列多行子查询。
目前全部的子查询,都是在where字句中充当判断条件,但是查询出来的临时表结构,在本质是也是表。
5.在from字句中使用子查询
子查询语句出现在from子句中----将一个子查询返回的数据作为一个临时表使用。
案列1:显示每个高于自己部门平均工资的员工姓名,部门,工资,平均工资,最后拿到每个人的办公地点
先拿到每个部门的平均工资:
select avg(sal) from emp group by deptno;

再将部门平均工资表和员工表做笛卡尔积,

拿到员工部门号和平均工资部门号相同的,

再将工资进行比较

最后将打印信息进行筛选

再将上表交给from拿到这些人的办公地点
select t1.ename,dept.loc,t1.deptno from dept,(select emp.ename,emp.deptno from emp,(select deptno,avg(sal) 部门平均工资 from emp group by deptno) tmp where emp.deptno=tmp.deptno and emp.sal>tmp.部门平均工资) t1 where t1.deptno=dept.deptno;

案列2:查找每个部门工资最高的人的姓名,工资,部门,最高工资
先拿到每个部门工资最高的人

再将这张表交给from与emp表进行笛卡尔积

再除去工资不匹配的

再比对部门是否一致

最后除去无用信息

案例3:显示每个部门的部门名,编号,地址和人员数量
先拿到每个部门的人员数量

再将上表交给from与dept表进行笛卡尔积

再筛选出两边部门号一致的数据

得到结果
解决多表问题的本质:想办法将多表转换成为单表,所以MySQL中,所有select问题全部都可以转换成单表问题。
6.合并查询
在实际应用中,为了合并多个select的执行结果,可以使用集合操作符号union,union all2
6.1union
union用于取得两个结果集的并集。当使用改操作符时,会自动去掉结果集中的重复行。
案例:将工资大于2500或职位时MANAGER的人展示
先找工资大于2500的员工

再找职位为MANAGER的员工

最后取得两个结果集的并集

6.2union all
取两结果的并集,不对结果中的重复行去除。
案例:同样将工资大于2500或职位为MANAGER的人展示
select * from emp where sal>2500 union all select * from emp where job='MANAGER';
