MYSQL(DQL数据查询语言下)

前言

今天为大家分享的是DQL数据查询语言的后续部分知识点,
上一篇博客已经分享了DQL数据查询语言的概念、特点、
基本的SELECT语句、过滤和排序数据以及分组查询!

DQL前文:DQL数据查询语言前文部分

分组查询

(一)、过滤分组Having 子句

1、语法: select 查询列表 from 表 【where 筛选条件】 group by 分组的字段 【order by 排序的字段】;

2、特点:

1、和分组函数一同查询的字段必须是group by后出现的字段

2、筛选分为两类:分组前筛选和分组后筛选

分组前筛选 分组后筛选
针对的是原始表 针对的是group by后的结果集
where关键字 having关键字

3、分组前筛选:

案例1:查询邮箱中包含a字符的 每个部门的最高工资

SELECT MAX(salary),department_id
FROM t_mysql_employees
WHERE email LIKE '%a%'
GROUP BY department_id;

结果:
在这里插入图片描述
案例2:延伸案例1,得出以下结论!

SELECT MAX(salary),manager_id,department_id
FROM t_mysql_employees
WHERE email  LIKE  '%a%'
GROUP BY department_id;

结论:虽然可以查询出结果,但是结果不一定正确,因为一个部门里面不可能只有一个员工,所以说最好按照查询出来的列名进行分组!

在这里插入图片描述

分组后筛选:

案例2:每个工种有奖金的员工的最高工资>12000的工种编号和最高工资

SELECT job_id,MAX(salary)
FROM t_mysql_employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>12000;

结果:
在这里插入图片描述
(二)、where条件筛选和having条件筛选的区别以及应用场景:

例1:查询员工数大于5的部门

SELECT COUNT(*),department_id

FROM t_mysql_employees

WHERE   salary>12000

GROUP BY department_id;

例2:查询员工数大于5的部门

SELECT COUNT(*),department_id

FROM t_mysql_employees

GROUP BY department_id

HAVING salary>12000;

结果如下:
在这里插入图片描述
结论:虽然两种方式的最终运行结果是一样的,但是其实内在的使用逻辑不一样,where关键字是先进行条件的判断,再筛选;反之,having关键字是先进行筛选,再进行判断的,只是由于表的设计,所以运行结果一样,并不是说两者之间没有区别,所以容易混淆!

注意:having后带的条件必须是整个sql语句中select查询出来的列!

案例2:每个工种有奖金的员工的最高工资>12000的工种编号和最高工资

首先分析题中的条件:

1、每个工种 意思是按照工种分组 group by job_id

2、有奖金 意思是奖金率不为空 使用where条件

3、最高工资>12000 意思是分组后筛选 使用having关键字

SELECT job_id,MAX(salary)

FROM t_mysql_employees

WHERE commission_pct IS NOT NULL

GROUP BY job_id

HAVING MAX(salary)>12000;

结论:当我们看到这样的sql语句时,要学会分析条件!
在这里插入图片描述
4、添加排序

案例:每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,按最高工资升序

SELECT job_id,MAX(salary) m

FROM t_mysql_employees

WHERE commission_pct IS NOT NULL

GROUP BY job_id

HAVING m>6000

ORDER BY m ;

这里也需要案例题目中的条件!

在这里插入图片描述

5、按照多个字段分组

案例:查询每个工种每个部门的最低工资,并按最低工资降序

SELECT MIN(salary),job_id,department_id

FROM t_mysql_employees

GROUP BY department_id,job_id

ORDER BY MIN(salary) DESC;

在这里插入图片描述

多表查询

1、原因:为了避免笛卡尔集,可以在 WHERE 加入有效的连接条件

2、笛卡尔集:

2.1、省略连接条件

2.2、 连接条件无效

2.3、所有表中的所有行可以互相连接

3、笛卡尔集只是一种组合方式而已!

案例:查询出女生名对应的男生名字

SELECT NAME,boyName 
FROM t_mysql_boys,t_mysql_beauty
WHERE beauty.boyfriend_id= boys.id;

一、等值连接

特点:

1、多表等值连接的结果为多表的交集部分
2、表连接,至少需要n-1个连接条件
3、表的顺序没有要求
4、般需要为表起别名
5、以搭配前面介绍的所有子句使用,比如排序、分组、筛选

1、给表格起别名

目的:1、提高语句的简洁度 2、区分多个重名的字段

案例:查询员工名、工种号、工种名

SELECT e.last_name,e.job_id,j.job_title

FROM t_mysql_employees  e,jobs j

WHERE e.`job_id`=j.`job_id`;

2、调换两个表格之间的顺序

案例:查询员工名、工种号、工种名

SELECT e.last_name,e.job_id,j.job_title

FROM t_mysql_jobs j,t_mysql_employees e

WHERE e.`job_id`=j.`job_id`;

3、可以加筛选

案例:查询有奖金的员工名、部门名

SELECT last_name,department_name,commission_pct

FROM t_mysql_employees e,t_mysql_departments d

WHERE e.`department_id`=d.`department_id`

AND e.`commission_pct` IS NOT NULL;

4、可以加分组

案例1:查询每个城市的部门个数

SELECT COUNT(*) 个数,city

FROM t_mysql_departments d,t_mysql_locations l

WHERE d.`location_id`=l.`location_id`

GROUP BY city;

5、可以加排序

案例2:查询每个工种的工种名和员工的个数,并且按员工个数降序

SELECT job_title,COUNT(*)

FROM t_mysql_employees e,t_mysql_jobs j

WHERE e.`job_id`=j.`job_id`

GROUP BY job_title

ORDER BY COUNT(*) DESC;

6、可以三表连接

案例:查询员工名、部门名、工种名,并按部门名降序

SELECT last_name,department_name,job_title

FROM t_mysql_employees e

INNER JOIN t_mysql_departments d ON 

e.`department_id`=d.`department_id`

INNER JOIN t_mysql_jobs j ON e.`job_id` = j.`job_id`

ORDER BY department_name DESC;

7、自连接

案例:查询员工的名字、上级的名字

 SELECT e.last_name,m.last_name
 
 FROM t_mysql_employees e
 
 JOIN t_mysql_employees m
 
 ON e.`manager_id`= m.`employee_id`;

二、外连接

1、应用场景:用于查询一个表中有,另一个表没有的记录;

2、几种连接类型的特点:

连接类型 特点
外连接 外连接的查询结果为主表中的所有记录
左外连接 左外连接,left join左边的是主表
右外连接 右外连接,right join右边的是主表

左外连接:

案例1:查询哪个部门没有员工

 SELECT d.*,e.employee_id
 
 FROM t_mysql_departments d
 
 LEFT OUTER JOIN t_mysql_employees e
 
 ON d.`department_id` = e.`department_id`
 
 WHERE e.`employee_id` IS NULL;

右外连接:

 SELECT d.*,e.employee_id
 
 FROM t_mysql_employees e
 
 RIGHT OUTER JOIN t_mysql_departments d
 
 ON d.`department_id` = e.`department_id`
 
 WHERE e.`employee_id` IS NULL;

全外连接:

 USE girls;#使用该数据库
 SELECT b.*,bo.*
 FROM t_mysql_beauty b
 FULL OUTER JOIN t_mysql_boys bo
 ON b.`boyfriend_id` = bo.id;

交叉连接:

 SELECT b.*,bo.*
 
 FROM t_mysql_beauty b
 
 CROSS JOIN boys bo;

1、全外连接=内连接的结果+表1中有 但表2没有的+表2中有 但表1没有 2、左外连接和右外连接即使交换两个表的顺序,也能实现同样的效果! 3、如果从表中有和它匹配的,则显示匹配的值 如果从表中没有和它匹配的,则显示null 外连接查询结果=内连接结果+主表中有而从表没有的记录

常见函数

1、字符函数

作用 函数 结果
转小写 LOWER(‘SQL Course’) sql course
转大写 UPPER(‘SQL Course’) SQL COURSE
拼接 CONCAT(‘Hello’, ‘World’) HelloWorld
截取 SUBSTR(‘HelloWorld’,1,5) Hello
长度 LENGTH(‘HelloWorld’) 10
字符出现索引值 INSTR(‘HelloWorld’, ‘W’) 6
字符截取后半段 TRIM(‘H’ FROM ‘HelloWorld’) elloWorld
字符替换 REPLACE(‘abcd’,‘b’,‘m’) amcd

注意:mysql本身是不区分大小写的,但是为了实现DBA(数据工程师)的一些需求,我们可以使用函数进行大小写之间的转换!

案例1:大小写转换

SELECT UPPER('john');

SELECT LOWER('joHn');

案例2:将姓变大写,名变小写,然后拼接

SELECT CONCAT(UPPER(last_name),LOWER(first_name)) 

 姓名 FROM t_mysql_employees;

2、数字函数

作用 函数 结果
四舍五入 ROUND(45.926, 2) 45.93
截断 TRUNC(45.926, 2) 45.92
求余 MOD(1600, 300) 100

案例1:四舍五入

SELECT ROUND(-1.55);
SELECT ROUND(1.567,2);

四舍五入的数字函数会使用得较多!

3、日期函数

作用 函数 结果
获取当前日期 now() 当前时间
字符转换成指定格式的日期 STR_TO_DATE(‘9-13-1999’,’%m-%d-%Y’) 1999-09-13
将日期转换成字符 DATE_FORMAT(‘2018/6/6’,‘%Y年%m月%d日’) 2018年06月06日

字符转日期和日期转字符这两种日期函数在很多大型公司中会使用得较多,其中m表示的是月份,d表示的是日,Y表示的是年份!

分页查询

1、应用场景:

当要显示的数据,一页显示不全,需要分页提交sql请求;

2、语法:

select 查询列表 from 表 【join type join 表2 on 连接条件 where 筛选条件 group by 分组字段 having 分组后的筛选 order by 排序的字段】 limit 【offset,】size;

offset要显示条目的起始索引(起始索引从0开始)
size 要显示的条目个数

案例1:查询前五条员工信息

SELECT * FROM  t_mysql_employees LIMIT 0,5;
SELECT * FROM  t_mysql_employees LIMIT 5;

案例2:查询第11条——第25条

SELECT * FROM  t_mysql_employees LIMIT 10,15;

案例3:有奖金的员工信息,并且工资较高的前10名显示出来

SELECT 
    * 
FROM
    t_mysql_employees 
WHERE commission_pct IS NOT NULL 
ORDER BY salary DESC 
LIMIT 10 ;

子查询

1、含义

出现在其他语句中的select语句,称为子查询或内查询,
外部的查询语句,称为主查询或外查询

2、按照子查询出现的位置:

位置 作用
select后面 仅仅支持标量子查询
from后面 支持表子查询
where或having后面 标量子查询(单行) 列子查询 (多行) 行子查询
exists后面 (相关子查询) 表子查询

3、案例1:谁的工资比 Abel 高?

①查询Abel的工资

SELECT salary
FROM t_mysql_employees
WHERE last_name = 'Abel'

②查询员工的信息,满足 salary>①结果

SELECT *
FROM t_mysql_employees
WHERE salary>(
	SELECT salary
	FROM t_mysql_employees
	WHERE last_name = 'Abel'
);

总结

今天的博客就分享到这啦,注意书写sql语句前分析,学会分析也很重要,遇到错误不要慌,一步一步地进行分析,说不定就能得出结果啦,欢迎评论区留言交流,告辞!
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45464930/article/details/106804902