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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 学习自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
目录
相关文章
|
8天前
|
SQL 存储 缓存
浅析MySQL中的SQL执行过程
本文探讨了MySQL的体系结构、SQL执行流程及SQL执行时间分析方法。首先介绍了MySQL由连接层、SQL层和存储引擎层构成;接着详细描述了SQL从客户端发送到服务器执行的具体流程;最后,通过启用profiling功能,展示了如何分析SQL执行时间,并说明了MySQL 8.0版本后移除查询缓存的原因。
浅析MySQL中的SQL执行过程
|
23天前
|
SQL 关系型数据库 MySQL
【MySQL】根据binlog日志获取回滚sql的一个开发思路
【MySQL】根据binlog日志获取回滚sql的一个开发思路
|
23天前
|
SQL 存储 关系型数据库
【MySQL核心】MySQL 数据恢复-ibd2sql
【MySQL核心】MySQL 数据恢复-ibd2sql
|
15天前
|
SQL 监控 安全
SQL Server的安全注意事项
将上述注意事项纳入日常的数据库管理中,有助于确保SQL Server数据库的安全稳定运行。除了遵循这些最佳实践外,定期进行安全审计也是确保环境持续安全的关键。
18 7
|
19天前
|
SQL 关系型数据库 MySQL
【MySQL 慢查询秘籍】慢SQL无处遁形!实战指南:一步步教你揪出数据库性能杀手!
【8月更文挑战第24天】本文以教程形式深入探讨了MySQL慢SQL查询的分析与优化方法。首先介绍了如何配置MySQL以记录执行时间过长的SQL语句。接着,利用内置工具`mysqlslowlog`及第三方工具`pt-query-digest`对慢查询日志进行了详细分析。通过一个具体示例展示了可能导致性能瓶颈的查询,并提出了相应的优化策略,包括添加索引、缩小查询范围、使用`EXPLAIN`分析执行计划等。掌握这些技巧对于提升MySQL数据库性能具有重要意义。
50 1
|
11天前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
27 0
|
11天前
|
SQL 关系型数据库 MySQL
|
12天前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
71 0
|
21天前
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
91 2
|
16天前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~

热门文章

最新文章