Mysql_8 SQL 语句——DQL 例题及一些注意事项

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 学习自b站骆昊jackfrued 老师的网课以及黑马网课。

学习自b站骆昊jackfrued 老师的网课以及黑马网课。

简单排序——查询最大值、次大只

  1. 员工表中含有员工号、姓名、薪水、职位、补贴 、所在部门等信息。查询薪水最高的员工姓名和薪水值。

    做法①:最普通的子查询,先查出最大工资值,再筛选出员工表中工资值等于这个数的员工。

    做法②:limit 做法。先按薪水降序排序所有员工,再只 limit 1 取第一条员工信息。这种做法的局限性在 limit 介绍的时候我也有写,就是当最值不只一位的时候,这种方法只能查出1位员工。

    做法③:

    select `ename`,`salary` from `tb_employee` t1 where(
        select count(*) from `tb_employee` t2 where `t2`.`salary`>`t1`.`salary`
    )=0;-- 结尾改成1,就是工资第二高的人
  2. 查询除了 boss 外工资最高的人。

    在题1的基础上,用 where 排除掉 boss。

    select `ename`,`salary` from `tb_employee` 
    where `salary`=(
        select max(salary) from `tb_employee` where `position`<>'boss'
    );
  3. 查询月薪 top 3的人。

    这时出现了和题1一样的情况。用 limit ,可能会漏掉工资并列的第四人;因此,这里用题1的方法③最合适。

    select `ename`,`salary` from `tb_employee` t1 where(
        select count(*) from `tb_employee` t2 where `t2`.`salary`>`t1`.`salary`
    )<3 order by `salary` desc;
  4. 查询所有员工的姓名和年薪。年薪计算公式:月薪*12+补贴。

    题目很简单,但是遇到计算一定要注意数据是否 Not Null,如果出现 Null 数据结果也会变成 Null。要用 ifnull() 或 coalesce() 函数限制一下。

  5. 查询所有部门名称及员工人数。

    部门名称在部门表中,每个部门的人数则需要根据员工表中部门号统计。显然这里要先查出员工表的员工号和统计员工信息,再把结果表和部门表做连接。重点注意几种连接的不同。比如此题,即便有的部门没有员工,也要显示出来,因此应该部门表 left join 派生表。

    select dname,total from `tb_department` t1
    left join (
        select dname, ifnull(count(*), as total from `tb_department` t2 group by `stu_id`
    ) on t1.`stu_id`=t2.`stu_id`;
  6. 查询每个部门比本部门平均薪水高的员工名及薪水。记得说清楚列属于哪个表,不然报错 ambigious

    先按部门分组,查询出平均成绩和员工号表;再通过部门号和员工表连接,并筛选出薪水值大于平均值的。

    select sname,salary from `tb_employee` t1
    inner join (
        select avg(salary),dno from `tb_employee` group by dno;
    )t2 on t1.dno=t2.dno and t1.salary > t2.avg(salary);-- 两个连表条件
  7. 查询每个部门中薪水最高的员工的用户姓名、薪水、部门名称。

    派生表通过薪水值、部门号和员工表、部门表相连接。

  8. 查询薪水排名4-6员工的薪水、姓名、排名

    问题1:怎么查出排名?

    问题2:这题并没有想象中的简单。比如员工薪水前8名是5000,5000,4000,4000,3000,3000,3000,2000,那么其实第三、第四人两个人并列第三,4-6显示的排名值就应该是3,5,5

    解决:mysql 8的窗口函数可以解决排名 / top N 问题。

    ①不用窗口函数:

    系统变量一般不写@或写两个@@(可以通过 show variables 查询),自己定义的变量写一个@,赋值的方法:set @a=0;select@a:=0;而且变量也可以通过 as 起别名。

    我们先定义一个变量,变量从0开始,每次选择+1,就可以当做序号用了。

    set @a=0;
    select row_num,ename,salary from (
        select @a=@a+1 as `row_num`,ename,salary,(select @a:=0) -- @a 重新赋值为0
        from `tb_employee` order by salary desc
    ) where `row_num` between 4 and 6;-- 子查询中做了几次查询,@a 就加几次

    注意不要在括号里用 limit 3 offset 3,因为这样的话子查询就只会进行3次,@a 的值就只会从1到3.

    另外,每次查询时都要重新给@a 赋值为0,不然其值会累加。

  9. 查询每个部门薪水排名前两名的员工。

    Top N 问题通过题1的做法③解决。

    select eno,ename,salary,dno from `tb_employee` t1
    where (
        select count(*) from `tb_employee` t2 where t1.`dno`=t2.`dno` and t2.salary>t1.salary
    )<2 order by t1.dno asc, t1.salary desc;

窗口函数

内容来自:通俗易懂的学会:SQL 窗口函数 - 知乎

应用于组内排名和 Top N 类问题。 一般是处理 where 和 group by

窗口函数不光是函数,有一套完整的语法。

<窗口函数> over (partition by <用于分组的列名>
                order by <用于排序的列名>)

<窗口函数> 处放聚合函数或专用窗口函数。

窗口函数是以一个列的形式使用的。

专用窗口函数

rank、dese rank、row_number

img

partition by 和 group by 的区别

img

使用:

select `ename`,`sal`,
rank() over (order by `sal` desc)as `r1`,
dense_rank() over (order by `sal` desc)as `r2`,
row_number() over (order by `sal` desc)as `r3`
from `tb_emp`;

第八题窗口函数做法:加一个 where r between 4 and 6 的条件。

至于要用哪种专用函数,就要看要求了。

第九题窗口函数做法:因为产生了分组,因此不能直接用 where r <=2。但是窗口函数的分组后的列做筛选,既不能直接用 where 也不能用 having。应该把窗口函数的查询结果作为一个派生表,再用 where 做选择。

select `ename`,`sal`,`dno`
from(
    select `ename`,`sal`,`dno`,
    rank() over (partition by `dno` order by `sal` desc)as `r`
    from `tb_emp`
) `temp` where `r`<=2;-- 不能在派生表里直接筛选

窗口函数性能还是比较差的,业务中不应使用,数据分析师可能会常用一些。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
13天前
|
SQL 存储 缓存
浅析MySQL中的SQL执行过程
本文探讨了MySQL的体系结构、SQL执行流程及SQL执行时间分析方法。首先介绍了MySQL由连接层、SQL层和存储引擎层构成;接着详细描述了SQL从客户端发送到服务器执行的具体流程;最后,通过启用profiling功能,展示了如何分析SQL执行时间,并说明了MySQL 8.0版本后移除查询缓存的原因。
浅析MySQL中的SQL执行过程
|
3天前
|
存储 SQL 关系型数据库
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
MySQL调优主要分为三个步骤:监控报警、排查慢SQL、MySQL调优。 排查慢SQL:开启慢查询日志 、找出最慢的几条SQL、分析查询计划 。 MySQL调优: 基础优化:缓存优化、硬件优化、参数优化、定期清理垃圾、使用合适的存储引擎、读写分离、分库分表; 表设计优化:数据类型优化、冷热数据分表等。 索引优化:考虑索引失效的11个场景、遵循索引设计原则、连接查询优化、排序优化、深分页查询优化、覆盖索引、索引下推、用普通索引等。 SQL优化。
【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)
|
3天前
|
存储 关系型数据库 MySQL
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
覆盖索引、前缀索引、索引下推、SQL优化、EXISTS 和 IN 的区分、建议COUNT(*)或COUNT(1)、建议SELECT(字段)而不是SELECT(*)、LIMIT 1 对优化的影响、多使用COMMIT、主键设计、自增主键的缺点、淘宝订单号的主键设计、MySQL 8.0改造UUID为有序
MySQL高级篇——覆盖索引、前缀索引、索引下推、SQL优化、主键设计
|
1天前
|
SQL 监控 关系型数据库
MySQL数据库中如何检查一条SQL语句是否被回滚
检查MySQL中的SQL语句是否被回滚需要综合使用日志分析、事务状态监控和事务控制语句。理解和应用这些工具和命令,可以有效地管理和验证数据库事务的执行情况,确保数据的一致性和系统的稳定性。此外,熟悉事务的ACID属性和正确设置事务隔离级别对于预防数据问题和解决事务冲突同样重要。
9 2
|
4天前
|
SQL 关系型数据库 MySQL
SQL和MySQL
SQL和MySQL
14 1
|
4天前
|
SQL 关系型数据库 MySQL
MySQL根据某个字段包含某个字符串或者字段的长度情况更新另一个字段的值,如何写sql
MySQL根据某个字段包含某个字符串或者字段的长度情况更新另一个字段的值,如何写sql
12 0
|
17天前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
30 0
|
2月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
59 13
|
2月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
2月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
44 6