SQL基础查询笔记【动力节点的视频】

查询

这篇文章是来自于B站动力节点的MySQL视频 链接动力节点-MySQL_MySQL教程
不过这个视频可能不是很新了(因为用的是txt排版…)

下面是相关的表数据

mysql> desc dept; (部门表)
+--------+-------------+------+-----+---------+-------+
| Field  | Type        | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| DEPTNO | int(2)      | NO   | PRI | NULL    |       |		部门编号
| DNAME  | varchar(14) | YES  |     | NULL    |       |		部门名称
| LOC    | varchar(13) | YES  |     | NULL    |       |		部门位置
+--------+-------------+------+-----+---------+-------+

mysql> desc emp;(员工表)
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| EMPNO    | int(4)      | NO   | PRI | NULL    |       |	员工编号
| ENAME    | varchar(10) | YES  |     | NULL    |       |	员工姓名
| JOB      | varchar(9)  | YES  |     | NULL    |       |	工作岗位
| MGR      | int(4)      | YES  |     | NULL    |       |	上级领导编号
| HIREDATE | date        | YES  |     | NULL    |       |	入职日期
| SAL      | double(7,2) | YES  |     | NULL    |       |	月薪
| COMM     | double(7,2) | YES  |     | NULL    |       |	补助/津贴
| DEPTNO   | int(2)      | YES  |     | NULL    |       |	部门编号
+----------+-------------+------+-----+---------+-------+

mysql> desc salgrade; (工资等级表)
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| GRADE | int(11) | YES  |     | NULL    |       |		等级
| LOSAL | int(11) | YES  |     | NULL    |       |		最低薪资
| HISAL | int(11) | YES  |     | NULL    |       |		最高薪资
+-------+---------+------+-----+---------+-------+

条件查询

找出工资在1100-3000的员工,包括1100,3000

select ename,sal from where sal >= 1100 and sal <= 3000;
select ename,sal from emp where sal between 1100 and 300;//闭区间

可以用于字符串:

select ename from emp where ename between 'A' and 'C';//左闭右开

找出哪些人津贴为NULL或0:

select ename,sal,comn from emp where comn is null or comn = 0;//is not null;

注意:运算符的优先级不确定的时候加小括号:

找出薪资大于1000的并且部门编号是20或30部门的员工。

select ename,sal,deptno from emp where sal > 1000 and (deptno = 20 or deptno = 30);

in等同于or:表示集合

找出工作岗位是MANAGER和SALESMAN的员工?

select ename,job from emp where job = 'SALEMAM' or job = 'MANAGER';
select ename,job from emp where job in ('SALEMAM','MANAGER');//in后面的值不是区间,是具体的值

not in :不在这几个值当中。

模糊查询like

  • %代表任意多个字符,_代表任意一个字符
select ename from emp where ename like '%O%';
select ename from emp where ename like '%\_%';//转义字符(含_的)
select ename from emp where ename like '%T';//名字中最后一个为T

排序order by

默认是升序asc,desc表示降序

select ename , sal from emp order by sal;
select ename , sal from emp order by 2;//按第二列排
select ename , sal from emp order by sal desc;

按照工资的降序排列,当工资相同的时候再按照名字的升序排列:

select ename,sal from emp order by sal desc , ename asc;//前面的占主导地位,前面相等再调用后面的。

例如:找出工作岗位是SALESMAN的员工,并要求按照薪资的降序排列。

select 
	ename,job,sal
from
	emp
where
	job = 'SALEMAN'
order by 
	sal desc;

分组函数

多行处理函数;都是对“某一组”数据进行操作的。

  • count 计数
    • count(distinct job)–distinct(去重)
  • sum 求和
  • avg 平均
  • max
  • min

记住:所有的分组函数都是对“某一组”数据进行操作的

select sum(sal) from emp;==>忽略NULL
select count(*) from emp;//总人数ename 
select sum(comm) from emp;
select sum(comm) from emp where comm is not null; // 不需要额外添加这个过滤条件。sum函数自动忽略NULL。
  • 分组函数自动忽略NULL
  • 数学计算含NULL,则结果为NULL
  • ifnull(可能为NULL 的数据,被当作什么处理) ,单行处理函数。
  • 分组函数还有另一个名字:多行处理函数
    多行处理函数的特点:输入多行,最终输出的结果是1行
//ifnull() 空处理函数
   ifnull(可能为NULL的数据,被当做什么处理) : 属于单行处理函数。
select ename ,ifnull(comn,0) as comn from emp;
//计算每个员工的年薪
select ename ,(sal+ifnull(comn,0))*12 as yearsal from emp;

找出工资大于平均工资的员工:

select ename,sal from emp where sal > avg(sal);//ERROR

//1.找出平均工资      2.找出高于平均工资的员工
select ename ,sal from emp where sal > (select avg(sal) from emp);//子查询

注意:SQL语句中的分组函数不可以直接使用在where子句当中

==>因为group by 是在where后面执行

//一个完整的SQL语句:
select		5
	..
from		1
	..
where		2
	..//无法用分组函数
group by	3    之后才能用分组函数
	..
having 		4
	..
order by	6
	..

count(*)与count(某个字段)

  • count(*) :不是统计某个字段中数据的个数,而是统计总记录条数。(和某个字段无关)

  • count(comn):表示统计comn字段中不为NULL的数据总数量。

group by 和 having

group by :按照某个字段或者某些字段进行分组。

having:对分组后的数据进行再次过滤。

案例:
找出每个工作岗位的最高薪资
select max(sal),job from emp group by job;

注意:

  1. 当一条语句中有group by 的话,select后面只能跟分组函数和参与分组的字段

  2. 分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。

  3. 并且任何一个分组函数(count sum avg max min)都是在group by语句执行结束之后才会执行的。

  4. 当一条sql语句没有group by的话,整张表的数据会自成一组。

select ename ,max(sal),job from group by job;//ERROR

求每个工作岗位的平均薪资:

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

找出每个部门不同工作岗位的最高薪资:(联合分组)

select deptno,job,max(sal) from emp group by deptno,job;

找出每个部门的最高的薪资,要求显示薪资大于2500的数据:分步写

select max(sal),depton from emp group by deptno having max(sal) > 2900;//效率低
select max(sal),depton from emp where sal > 2900 group by deptno;

建议能够使用where过滤的尽量用where

找出每个部门的平均薪资,要求显示薪资大于2500的数据(having对分组数据过滤)

select deptno,avg(sal) from emp group by deptno having avg(sal) > 2500;

总结一个完整的DQL语句怎么写?

select			5
	..
from			1	
	..
where			2
	..
group by		3
	..
having			4
	..
order by		6
	..
// limit       7	

关于查询结果集的去重?

select distinct job from emp; // distinct关键字去除重复job记录。

记住:distinct只能出现在所有字段的最前面。

统计岗位的数量?

select count(distinct job) from emp;

连接查询

笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的乘积。

select 
	e.ename,d.dname
from
	emp e
join    //inner join
	dept d
on
	e.deptno = d.deptno;

内连接之非等值连接

INNER JOIN 只会保留两个表都存在的数据(还记得之前的交集吗),这看起来意味着一些数据的丢失,在某些场景下会有问题.

最大的特点是:连接条件中的关系是非等量关系。

找出每个员工的工资等级,要求显示员工名、工资、工资等级。

select 
	e.ename,e.sal,s.grade
from
	emp e
join            // inner可以省略
	salgrade s
on
	e.sal between s.losal and s.hisal;

自连接

最大的特点是:一张表看做两张表。自己连接自己

案例:找出每个员工的上级领导,要求显示员工名和对应的领导名。

员工的领导编号 = 领导的员工编号

select 
	a.ename as '员工名',b.ename as '领导名'
from
	emp a
inner join
	emp b
on
	a.mgr = b.empno;

外连接

内连接:
假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。
AB两张表没有主副之分,两张表是平等的。

外连接:
假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表,当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。

外连接的分类?
左外连接(左连接):表示左边的这张表是主表。
右外连接(右连接):表示右边的这张表是主表。

外连接最重要的特点是:主表的数据无条件的全部查询出来

找出哪个部门没有员工?

select 
	d.*
from
	emp e
right join
	dept d
on
	e.deptno = d.deptno
where
	e.empno is null;

三张表的连接查询


A
join
B
join
C
on

表示:A表和B表先进行表连接,连接之后A表继续和C表进行连接。

案例:找出每一个员工的部门名称以及工资等级:

select 
	e.ename,d.dname,s.grade
from
	emp e
join
	dept d
on
	e.deptno = d.deptno
join
	salgrade s
on
	e.sal between s.losal and s.hisal;
查询结果:
+--------+------------+-------+
| ename  | dname      | grade |
+--------+------------+-------+
| SMITH  | RESEARCH   |     1 |
| ALLEN  | SALES      |     3 |
| WARD   | SALES      |     2 |
| JONES  | RESEARCH   |     4 |
| MARTIN | SALES      |     2 |
| BLAKE  | SALES      |     4 |
| CLARK  | ACCOUNTING |     4 |
| SCOTT  | RESEARCH   |     4 |
| KING   | ACCOUNTING |     5 |
| TURNER | SALES      |     3 |
| ADAMS  | RESEARCH   |     1 |
| JAMES  | SALES      |     1 |
| FORD   | RESEARCH   |     4 |
| MILLER | ACCOUNTING |     2 |
+--------+------------+-------+

找出每一个员工的部门名称、工资等级、以及上级领导。<把上面的合起来>

select 
	e.ename '员工',d.dname,s.grade,e1.ename '领导'
from
	emp e
join
	dept d
on
	e.deptno = d.deptno
join
	salgrade s
on
	e.sal between s.losal and s.hisal
left join
	emp e1
on
	e.mgr = e1.empno;

子查询

1. where子句中使用子查询

案例:找出高于平均薪资的员工信息。

select * from emp where sal > (select avg(sal) from emp);

2. from后面嵌套子查询

找出每个部门平均薪水的等级。

第一步:找出每个部门平均薪水(按照部门编号分组,求sal的平均值)
select deptno,avg(sal) as avgsal from emp group by deptno;

第二步:将以上的查询结果当做临时表t,让t表和salgrade s表连接,条件是:t.avgsal between s.losal and s.hisal

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

找出每个部门平均的薪水等级。

第一步:找出每个员工的薪水等级。
select e.ename,e.sal,e.deptno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
第二步:基于以上结果,继续按照deptno分组,求grade平均值。

select 
	e.deptno,avg(s.grade)
from 
	emp e 
join 
	salgrade s 
on 
	e.sal between s.losal and s.hisal
group by
	e.deptno;

3. 在select后面嵌套子查询

案例:找出每个员工所在的部门名称,要求显示员工名和部门名。

select 
	e.ename,d.dname
from
	emp e
join
	dept d
on
	e.deptno = d.deptno;
//总和
select 
	e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname 
from 
	emp e;

union

(可以将查询结果集相加)

案例:找出工作岗位是SALESMAN和MANAGER的员工

select ename,job from emp where job = 'MANAGER'
union
select ename,job from emp where job = 'SALESMAN';

limit

  1. limit是mysql特有的,其他数据库中没有,不通用。(Oracle中有一个相同的机制,叫做rownum)

  2. limit取结果集中的部分数据,这时它的作用。

  3. 语法机制:
    limit startIndex, length
    startIndex表示起始位置,从0开始,0表示第一条数据。
    length表示取几个

通用的标准分页sql

每页显示3条记录:
第1页:0, 3
第2页:3, 3
第3页:6, 3
第4页:9, 3
第5页:12, 3

每页显示pageSize条记录:

第pageNo页:(pageNo - 1) * pageSize, pageSize

pageSize是:是每页显示多少条记录
pageNo是:显示第几页

java代码{
int pageNo = 2; // 页码是2
int pageSize = 10; // 每页显示10条

limit (pageNo - 1) * pageSize, pageSize

}

猜你喜欢

转载自blog.csdn.net/qq_45737419/article/details/106078598