SQL语句是一门通用的数据库语言,当你学习了SQL的话那么你在利用其它的关系型数据库进行操作的时候上手会很快

第一节 单表查询

什么是单表查询,顾名思义,单表查询就是在一张表中进行查询操作

WHERE 约束条件

查询id大于等于3小于等于6的数据
SELECT ID, NAME 
FROM EMP 
WHERE ID >= 3 AND ID <= 6

有没有很迷惑,其实我给你讲一下你就知道了,用咱们的语文!中国话
我选择, ID字段和,NMAE字段 从EMP的表里面 条件是 ID 大于3 且ID 小于6

另外一种
SELECT ID, NAME 
FROM EMP 
WHERE ID BETWEEN 3 AND 6

我选择 ID字段,和NAME字段从EMP的表里面查询 3和6 之间的数值

查询薪资大于20000 或者 18000 或者 17000

SELECT * 
FROM EMP
WHERE salary = 20000 or salary = 18000 or salary = 17000;
我选择所有的字段(*通配符) 从 EMP的表中 条件是 薪资大于20000 或者 18000 或者 17000

模糊查询 like

模糊查询 like
	1. % 匹配任意多个字符
	2. _: 匹配任意单个字符

查询员工姓名中包含字母O的员工姓名和薪资
SELECT NAME, SALARY 
FROM EMP 
WHERE NAME LIKE "%O%"
我选择 姓名  薪资  从EMP的表中  我的条件是NAME好像是O开头的

查询员工姓名是由资格字符组成的员工的姓名和薪资
SELECT NAME, SALARY 
FROM EMP
WHERE NAME LIKE "____"
我选择 姓名  薪资  从EMP的表中 我的条件是NAME好像是四个字符

查询id小于3 或者id 大于6的数据
SELECT * 
FROM EMP 
WHERE ID NOT BETWEEN 3 AND 6
我选择 所有字段 从EMP表中   条件是 两者之间的数值是 3和6

查询薪资不是 20000 , 18000 , 17000的数据
SELECT * 
FROM EMP 
WHERE SALART NOT IN(2000,18000, 17000)
我选择所有字段 从EMP表中 条件是 SALART不在20000,18000,17000之间的

查询岗位描述非空的员工姓名和岗位命(IS NOT NULL )
SELECT NAME,POST 
FROM EMP 
WHERE POST_COMMENT IS NOT MULL
我选择 NAME 和 POST 字段 从EMP的表中 条件是 POST_CPMMENT 并不是 空的

GROUP BY 分组

分组之后,最小的操作性单位应该是组,而不是组内的单个个数据
很多同学看道这个GROUP BY 就很懵具体是什么意思呢就是分组!!......
呐 你听了分组也蒙了..其实我第一次看看到分组也会蒙的,

id

name

dept

salary

edlevel

hiredate

1

张三

开发部

2000

3

2009-10-11

2

李四

开发部

2500

3

2009-10-01

3

王五

设计部

2600

5

2010-10-02

4

王六

设计部

2300

4

2010-10-03

5

马七

设计部

2100

4

2010-10-06

6

赵八

销售部

3000

5

2010-10-05

7

钱九

销售部

3100

7

2010-10-07

8

孙十

销售部

3500

7

2010-10-06

你看看dept字段是不是有很多重复的? 那么你按照这个表对dept分组的话那么就分成三个  也就相当于去重
如果你对不重复的字段进行分组的话,那么那会生成出八个数据
分组之后,最小的可操作性单位应该是组,而不是组内的单个数据

设置严格模式

set global sel_mode = 'strict_trans_tables, only_full_froup_by'

按照什么分组,就这能拿到什么,其他字段不能直接获取,需要结住集合函数,

1. 获取每个部门的最高薪资
SELECT POST AS "部门",max(salary) as "最高薪资"
FROM EMP GROUP BY POST;
我选择POST字段但是我起一个别的名字,部门,最大的薪资, 从emp表中 对部分进行分组
as 是起别名

2.获取每个部门的最低薪资
SELECT POST,MIN(SALARY)
FROM EMP GROUP BY POST;
我选择POST字段,和最小工资 从EMP表中对部门进行分组

3. 获取每个部门的平均薪资
SELECT POST, AVG(SALARY) 
FROM EMP 
GROUP BY POST;
我选择部门 和平均薪资 从 EMP表中对部门进行分组,查看

4.获取每个部门的薪资综合
SELECT POST,SUM(SALARY)
FROM EMP
GROUP BY POST;
我选择POST字段和综合的薪水,从EMP表中对部门进行分组查看

5. 获取每个部门的人数
SELECT POST, COUNT(ID)
FROM EMP 
GROUP BY POST
我选择从 POST表中对ID进行计算 从EMP 表中对POST部门进行分组

6.查询分组之后的部门名称和每个部门下的所有员工姓名
SELECT POST, GROUP_CONCAT(NAME)
FROM EMP 
GROUP BY POST;
我选择POST 字段对NAME进行截断 从EMP表中 对POST进行分组筛查

7.查询每个人的年薪
SELECT NAME,SALARY * 12 
FROM EMP;
我选择 NAME字段和对薪水进行乘与12的操作对EMP表进行查询

分组注意事项

关键子WHERE和 GROUP BY 同时出现的时候 GROUP BY 必须放在 WHERE后面
WHERE 先对整体数据进行过滤,在进行分组操作

聚合汗珠只能在分组之后使用
关键 WHERE的筛选条件不能使用聚合函数
SELECT ID, NAME,AGE 
FROM EMP 
WHERE MAX(SALARY) > 3000;
上面的是错误的

不分组默认整张表就是一个组
SELECT MAX(SALARY)
FROM EMP

统计各个部门年龄在30以上的员工平均薪资
SELECT POST,AVG(SALARU)
FROM EMP
WHERE AGE > 30
GROUP BY POST;
我选择POST 字段和平均的薪水,从EMP表中 条件是年龄要大于30 对部门进行分组

HAVING 分组之后的筛选的条件

HAVING的语法很WHERE是一致的,只不过HAVING是分组之后进行过滤操作的,
HAVING是可以直接使用聚合函数的

1. 统计个部门年龄在30岁以上的员工工资并且保留平均薪资大于10000的部门
SELECT POST ,AVG(SALARY)
FROM EMP 
WHERE AGE > 30 
FROUP BY POST
HAVING AVG(SALARY) > 10000;
我选择POST字段和平均薪资 从EMP条件是年龄大于30 然后对部门进行分组,再次筛选心碎大于10000的部门

distinct去重

一定要注意:必须是完全一样的数据才可以屈从(除了主键都一样,会被误认为是一样的数据,因为惯性思维下,序号(比如主键id)这一列会被忽略的)
	由主键存在的情况下是不可能去重的
	
	SELECT DISTINCT  AGE 
	FROM 
	我选择对年龄进行去重 在FROM这张表内

	注意关键子distinct的位置

ORDER BY 排序

SELECT * 
FROM EMP 
ORDER BY SALARY;
我选择所有字段从EMP表中对薪水进行去重

SELECT * 
FROM EMP 
ORDER BY SALARY;
我选择所有字段从EMP表中对薪水进行去重

SELECT * 
FROM EMP
ORDER BY SALATY ASC;
我选择所有字段 对EMP表 的薪水字段进行排序 但是是升序排序

ORDER BY 默认是升序,降序是desc

1.按照age降序排,如果相同,再按照salary升序排	
SELECT * 
FROM  RMP
ORDER BY AGE DESC 
SALARY ASC
我选则所有字段对EMP表进行排序对年龄去重 然后对salary升序排序

2.统计各个部门年龄在20岁以上的员工薪资,并且保留平均薪资大于1000的部门,然后对平均工资进行排序
SELECT POST,AVG(SALARY)
FROM EMP 
WHERE AGE > 20
GROUP BY POST
HAVING AVG(SALARY) > 1000
ORDER BY AVG(SALARY) DESC;
我选择 部门字段和平均薪水从EMP表中 条件是年龄大于20 然后对部门进行分组,再次过滤薪水大于1000的然后对年龄进行排序

LIMIT 限制展示条数

在工作中公司的表中有很多数据假如
SELECT * FROM EMP
如果由一万条数据,你是不是头皮发麻

SELECT * FROM EMP LIMIT 3;
w我选择 所有字段 从EMP表中 先展示3条数据
LIMIT 5,6 表示从第五条数据开始往后查找六条

多表查询

多表查询就两种方式
1.先拼接表在查询
2.子查询,一步一步查询处结果

连表查询

SELECT * 
FROM EMP,DEP
WHERE EMP.DEP_ID =  DEP.ID
我选择所有从 EMP和DEP两张表中 条件是DEP_ID=DEP.ID;

内连接 INNER JOIN

两张表互相迁就,不会出现NULL的情况,只能拼接两张表中有联系的部分

左连接 LEFT JOIN

以左边表为主,右边的表迁就左边表,右边表与左边表对应的数据如果不村子就填NULL

右链接 RIGHT JOIN

以右边的表为主,左边的表"迁就"右边表,左边表与右边表对应的数据如果不存在就填NULL

全连接 UNION

谁也不迁就谁,没有相应的数据直接NULL

SELECT * 
FROM EMP 
INNER JOIN DEP
ON EMP.DEP_IN = DEM.ID
我选择所有字段 从EMP表内连接到DEP的表中 链接的条件是 EMP.ID = DEM.ID

SELECT * 
FROM EMP 
LEFT JOIN DEP
ON EMP.DEP_ID = DEM.ID
我选择所有字段 从EMP表 左连接到 DEP表 选择字段是EMP.DEP_ID = DEM.ID

SELECT * 
FROM EMP
RIGHT JOIN DEP
ON DEP_ID = DEM.ID
我选择所有字段,从EMP表中有链接到 DEP表 链接条件是 EMP_ID = DEM.ID

SELECT * 
FROM  EMP 
LEFT JOIN  DEP
ON EMP.DEP_ID = DEM.ID;
UNION
SELECT *
FROM EMP 
RIGHT JOIN DEP 
ON EMP.DEP _ID = DEM.ID
我选择所有字段 从 EMP表中左连接DEP表条件是 EMP.DEP_ID = DEM.ID
还要再次链接
我选择所有字段 从 EMP表中右连接DEP表条件是 EMP.DEP_ID = DEM.ID

子查询

子查询的核心思想: 分步的取解决问题
子查询:将一个查询语句的结果当作另一个查询语句的条件来用

一.查询部门是技术或者人力资源字段的员工信息
	1.先取部门表获取到部门的ID号
	SELECT ID 
	FROM DEP 
	WHERE NAME = "技术" OR NAME = "人力资源"
	我选择 id字段 从dep表中条件是名字是技术,或者是人力资源的
	2.再去员工表筛选处对应的部门ID的员工
	SELECT NAME 
	FROM EMP 
	WHERE DEP_ID IN (
	SELECT ID 
	FROM DEP 
	WHERE NAME = "技术" OR NAME = "人力资源"
	)
	我选择名字字段 从EMP表中条件是dep_id 在 (我选择 id字段 从dep表中条件是名字是技术,或者是人力资源的)
	
总结:
	表的查询结果可以作为其他表的查询条件
	可以通过起别名的方式把表的查询结果作为一张虚拟表跟其他表关联

练习题

查询所有课程名称以及对应的任课老师的名字
1.先做连表的操作
SELECT * 
FROM COURSE 
INNER JOIN TEACHER
ON COURSE.TEACHER_ID = TEACHER.TID
我选择所有字段 从course 内连接到 TEACHER表 条件是 TEACHER_ID = TEACHER.tid
2. 连表完成之后,两张表就变成了一张表,查询到这一张表中对应的字段即可(把上面的*韩城指定字段就好)
SELECT COURSE.CNAME, TEACHER.THNAME
FROM  COURSE
INNER JOIN TEACHER
ON COURSE.TEACHER_ID = TEACHER.TID

查询平均成绩大于八十分的同学的姓名和平均成绩
1.先做连表操作
SELECT * 
FROM SCORE 
INNER JOIN STUDENT 
ON STUDENT_ID = STUDENT.SID;
2.平均成绩大于八十分的同学,按照学城(学城ID,学生姓名分组
GROUP BY SCORE.SID
3.平均成绩大于八十分,即进行筛选而且平均是聚合函数,所以使用having
having avg(num) > 80
3. 因为以学生ID分组,所以可以获取学生ID和平均成绩
SELECT SORE.STUDENT_ID,AVG(NUM) AS AVG_NUM
4. 需要获取的是:学生的姓名和平均成绩,所以用student表和上面得到的虚拟表再做一次连表操作
SELECT  STUDENT.SUNME,T1.AVG_NUM
FROM STUDENT 
INNER JOIN(
	 SELECT SCORE.STUDENT_ID,AVG(NUM) AS AVG_NUM
	 FROM SCORE 
	 INNER JOIN STUDENT 
	 ON SORE.STUDENT_ID = STUDENT.SID
	 GROUP BY SCORE.SID
	 HAVING AVG(NUM) > 80) AS T1 
	 ON STUDENT.SID = T1.STUDENT_iD;
我选择 从学生表的学生姓名 和t1表的avg_num字段 从 学生表进行链接 条件是 我选择分数表中对应的学生id 和平均成绩从  分数表 链接 学生表 条件是分数的学生id等于学生自己的id 对分数的进行分组 过滤大于80的 ...  你自己缕把 中华话我说不利索了