SQL-子查询;union;limit

Posted MinggeQingchun

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL-子查询;union;limit相关的知识,希望对你有一定的参考价值。

一、子查询

select语句中嵌套select语句,被嵌套的select语句称为子查询

子查询可以出现在 select,from,where等关键字之后

    select
		...(select)...
	from
		...(select)...
	where
		...(select)...

1、where后的子查询

分组函数不能够直接使用在where子句中

mysql> select empname,sal from emp where sal > min(sal);
ERROR 1111 (HY000): Invalid use of group function

分组函数在使用的时候必须先分组之后才能使用

where执行的时候,还没有分组;所以where后面不能出现分组函数

 select sum(sal) from emp; 

这个没有分组,sum()函数可以使用,是因为select在group by之后执行

如:查询比最低工资高的员工姓名和工资

select empname,sal from emp where sal > (select min(sal) from emp);

2、from后子查询

from后面的子查询,可以将子查询的查询结果当做一张临时表

查询每个岗位的平均工资的薪资等级

(1)先按照岗位分组求平均值,将查询结果看做临时表temp

select job,avg(sal) as avgsal  from emp group by job;

 (2)将薪资等级查询看做一张 s 表

select * from salgrade;

(3)将临时表temp 和 s 表结合查询

select 
    temp.*,s.grade 
from 
    (select job,avg(sal) as avgsal  from emp group by job) as temp 
join 
    salgrade s 
on 
    temp.avgsal between s.losal and s.hisal;

 3、select后子查询

查询每个员工的部门名称,显示员工名,部门名

select 
    e.empname,e.deptno,
    (select d.deptname from dept d where e.deptno = d.deptno) as deptname 
from 
    emp e;

注:

对于select后面的子查询来说,这个子查询只能一次返回1条结果,多于1条,就报错

如下,如果不过滤部门编号,就会报错

mysql> select e.empname,e.deptno,(select d.deptname from dept d ) as deptname from emp e;
ERROR 1242 (21000): Subquery returns more than 1 row

二、union

UNION 操作符用于合并两个或多个 SELECT 语句的结果集

注:

UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型

同时,每个 SELECT 语句中的列的顺序必须相同

如下,都会报错

列数不同

select empname,job from emp where job = 'salesman' union select empname from emp where job='manager';
ERROR 1222 (21000): The used SELECT statements have a different number of columns

字段类型不同;MYSQL中可以不会报错,但是Oracle语法严格 ,会报错

select 
    empname,job 
from 
    emp 
where 
    job = 'salesman' 
union 
select 
    empname,sal 
from 
    emp 
where 
    job='manager';

UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名

(2)union 和 join 选择

union的效率要高一些

join表连接,每连接一次新表,则匹配的次数满足笛卡尔积,是两张表行数的乘积

union可以减少匹配的次数;还可以完成两个结果集的拼接

如下:a 连接 b;连接 c

a表10条记录;b表 10条记录;c表 10条记录;join匹配次数:10*10*10 = 1000

a 连接 b一个结果:10 * 10  = 100; a 连接 c一个结果:10 * 10 = 100次;union匹配次数:100 + 100 = 200次

(union把乘法变成了加法运算)

三、limit

limit子句用于限制查询结果返回的数量;通常使用在分页查询当中

分页的作用是为了提高用户的体验;一次全部都查出来,用户体验差,可以一页一页加载翻页看

语法如下:

select 
    ... 
from 
    tableName 
limit 
    startindex,length

startindex:为查询结果的索引值(默认从0开始)

length:数量长度

可以省略startindex索引,默认取前length条数

select 
    ... 
from 
    tableName 
limit 
    length

如:按照薪资降序,取出排名在前5名的员工

    select 
		ename,sal
	from
		emp
	order by 
		sal desc
	limit 5; //取前5

或者

	select 
		ename,sal
	from
		emp
	order by 
		sal desc
	limit 0,5;

如:查询工资排名在[3-5]名的员工;2表示起始位置从下标2开始,第三条记录;3表示长度

select * from emp order by sal desc limit 2,3;

分页;如每页显示10条数据,每页条数pageSize = 10;页码 pageNum = 1起始

第1页:limit 0,10        [0-9]
第2页:limit 10,10      [10-19]
第3页:limit 20,10      [20-29]
......

limit (pageNum -1)*pageSize , pageSize

四、DQL语句最终版执行顺序

select 
	...
from
	...
where
	...
group by
	...
having
	...
order by
	...
limit
	...

执行顺序
1、from
2、where
3、group by
4、having
5、select
6、order by
7、limit..

以上是关于SQL-子查询;union;limit的主要内容,如果未能解决你的问题,请参考以下文章

MySQL笔记--- 连接查询;子查询;union;limit;

09_MySQL笔记-组函数-GROUP BY-LIMIT-多表连接查询-子查询-UNION-索引-视图-存储过程

带有 LIMIT 的 SQL UNION 是不是优化了不需要的查询?

SQL:使用 UNION、ORDER BY 和 LIMIT 进行选择

SQL中Union与Union All的区别

使用 sql union 子查询组合来处理客户过滤的 AND/OR 条件组合