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
目录
相关文章
|
18天前
|
SQL NoSQL 关系型数据库
2024Mysql And Redis基础与进阶操作系列(5)作者——LJS[含MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页等详解步骤及常见报错问题所对应的解决方法]
MySQL DQL基本查询:select;简单、排序、分组、聚合、分组、分页、INSERT INTO SELECT / FROM查询结合精例等详解步骤及常见报错问题所对应的解决方法
|
30天前
|
SQL 运维 关系型数据库
MySQL 运维 SQL 备忘
MySQL 运维 SQL 备忘录
46 1
|
1月前
|
SQL 存储 数据可视化
SQL中文字符旋转90度的处理:技巧、方法与注意事项
在SQL数据库中,直接对文本数据进行90度旋转并不是数据库系统的原生功能
|
1月前
|
SQL 存储 关系型数据库
SQL文件导入MySQL数据库的详细指南
数据库中的数据转移是一项常规任务,无论是在数据迁移过程中,还是在数据备份、还原场景中,导入导出SQL文件显得尤为重要。特别是在使用MySQL数据库时,如何将SQL文件导入数据库是一项基本技能。本文将详细介绍如何将SQL文件导入MySQL数据库,并提供一个清晰、完整的步骤指南。这篇文章的内容字数大约在
136 1
|
19天前
|
SQL 关系型数据库 MySQL
MySql5.6版本开启慢SQL功能-本次采用永久生效方式
MySql5.6版本开启慢SQL功能-本次采用永久生效方式
33 0
|
19天前
|
SQL 关系型数据库 MySQL
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
mysql编写sql脚本:要求表没有主键,但是想查询没有相同值的时候才进行插入
30 0
|
1月前
|
SQL 存储 关系型数据库
mysql 数据库空间统计sql
mysql 数据库空间统计sql
45 0
|
1月前
|
SQL 存储 关系型数据库
mysql SQL必知语法
本文详细介绍了MySQLSQL的基本语法,包括SELECT、FROM、WHERE、GROUPBY、HAVING、ORDERBY等关键字的使用,以及数据库操作如创建、删除表,数据类型,插入、查询、过滤、排序、连接和汇总数据的方法。通过学习这些内容,读者将能更好地管理和操
14 0
|
3月前
|
SQL 关系型数据库 数据库
|
5月前
|
SQL 前端开发 关系型数据库
零基础学习数据库SQL语句之查询表中数据的DQL语句
零基础学习数据库SQL语句之查询表中数据的DQL语句
36 0