精讲Mysql各种高难度Sql编写(一)
sql1
sql2
sql3
   在每年的面试高峰期,面试官为了筛选优秀的Java研发人员 ,往往会在面试题里面增加编写sql,普通的sql大家都会写,所以会把sql的难度提高。
   所以,今天这篇高难度sql,是为了解决大家在面试的难题,从sql脚本,数据插入,sql的CRUD,以及高难度查询,基本上面面俱到。相信能给小伙伴们一点帮助!
一、首先,为了让大家能够看懂后面的sql,需要复习一下基础。下面是两表sql查询的几种方式,单表的增删改查就不讲了,相信大家都会。然后,这里,需要强调一下,mysql是不支持full join的,Oracle支持

二、然后说下笛卡尔积,有些小伙伴可能不知道,简单描述一下,就是一张表的每一列与另外一张表的每一列,一 一匹配,形成总数据工作中不推荐,容易产生冗余数据,它跟上面的 inner join的不同是,上面加了where条件
笛卡尔积的三种写法:
select * from t1 join t2;
select * from t1 inner join t2;
select * from t1, t2;

三、我们用LeetCode数据库,第176题作为热身题

sql1
sql脚本
DROP TABLE IF EXISTS employee;
CREATE TABLE employee (
id int(0) NOT NULL AUTO_INCREMENT,
salary decimal(10, 2) NULL DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO employee VALUES (1, 100.00);
INSERT INTO employee VALUES (2, 200.00);
INSERT INTO employee VALUES (3, 300.00);

要求:查询第二高的薪水

写法一、使用 IFNull 函数判断是否为空,如果为空返回Null
使用 distinct 关键字对薪水去重

select IFNULL((select distinct salary from employee order by salary desc limit 1,1),NULL) as secondTop
1
写法二、 利用Max,not in 嵌套查询

select max(salary) from employee where salary not in (select max(salary) from employee)
1
写法三、使用Mysql函数查询,首先需要打开binlog,函数开关

set global log_bin_trust_function_creators=TRUE;
1
创建函数,简单说下,dense_rank() Mysql 8.0窗口函数,然后必须搭配 over使用,在over里面增加排序,用where做条件过滤,where后面不要用rank,那是关键字

CREATE FUNCTION getSecondSalary(N INT) RETURNS INT
BEGIN
RETURN (
SELECT
DISTINCT salary
FROM
(SELECT
salary, dense_rank() over(ORDER BY salary DESC) AS ranks
FROM
employee) tmp
WHERE ranks = N
);
END
1
2
3
4
5
6
7
8
9
10
11
12
13
执行函数,查询排名第二的薪水

select getSecondSalary(2)
1
sql2
LeetCode 180题

要求:编写一个 SQL 查询,查找所有至少连续出现三次的数字

sql 脚本
DROP TABLE IF EXISTS numbers;
CREATE TABLE numbers (
id int(0) NOT NULL AUTO_INCREMENT,
Num int(0) NULL DEFAULT NULL,
PRIMARY KEY (id) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO numbers VALUES (1, 1);
INSERT INTO numbers VALUES (2, 1);
INSERT INTO numbers VALUES (3, 1);
INSERT INTO numbers VALUES (4, 2);
INSERT INTO numbers VALUES (5, 1);
INSERT INTO numbers VALUES (6, 2);
INSERT INTO numbers VALUES (7, 2);

方法一、官方解法,我只能说牛批,大概的意思是,既然是3个连续的数字,那么我就给3张一样的表,让他们在不同的Id 下,Num相同。也就是说,把每一行当成一个表进行查询

SELECT DISTINCT
l1.Num AS ConsecutiveNums
FROM
numbers l1,
numbers l2,
numbers l3
WHERE
l1.Id = l2.Id - 1
AND l2.Id = l3.Id - 1
AND l1.Num = l2.Num
AND l2.Num = l3.Num
;
1
2
3
4
5
6
7
8
9
10
11
12
方法二、大神解法,当然不是我写的,哈哈哈
我来解读一下吧,相信很多小伙伴们,可能第一次看到这种写法,如果不解释的话,完全懵的。

    先从最后一个SELECT说起,为什么从最后一个说起,因为最后一个SELECT是开头,它定义了一个变量叫做 @pre等同于java里面的 String str,然后 := 就是java的=,还有一个变量是
@dcount,赋值为1

    然后从第二个SELECT说起,IF里面做判断,if里面的第三个参数的意思是elseif的结果,如果@pre 等于传进来的第一个数字,那么就加1,否则还是为1。

    说实话,FROM上面最近的 @pre := L.num ,我想了好久,才明白其中的意思,它的目的是相当于一次循环,因为IF执行完以后,需要再次判断里面的数据,那么L.num就把值给到@pre,就是相当于一次更新,那么,@pre一更新,IF就需要再判断一次,直到表里面的数据没有为止

    外面这个SELECT就不讲了,明白人都知道

SELECT DISTINCT num as ConsecutiveNums FROM(
SELECT
L.`num`,
IF(
@pre = L.`num`,
@dcount := @dcount + 1,
@dcount := 1
) AS dcounts,
@pre := L.`num`
FROM
`numbers` AS L,
(SELECT
@pre := NULL,
@dcount := 1) AS tmp) as t where t.dcounts >=3 ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
sql3
LeetCode 184题
要求: 查询每个部门工资最高的员工

sql 脚本
DROP TABLE IF EXISTS employee2;
CREATE TABLE employee2 (
Id int(11) DEFAULT NULL,
NAME char(10) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL,
Salary int(11) DEFAULT NULL,
DepartmentId char(2) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;

INSERT INTO employee2 VALUES (1, ‘Joe’, 70000, ‘1’);
INSERT INTO employee2 VALUES (2, ‘Hery’, 80000, ‘2’);
INSERT INTO employee2 VALUES (3, ‘Sam’, 60000, ‘2’);
INSERT INTO employee2 VALUES (4, ‘Max’, 90000, ‘1’);

DROP TABLE IF EXISTS department;
CREATE TABLE department (
Id int(11) DEFAULT NULL,
NAME char(10) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci ROW_FORMAT = Compact;

INSERT INTO department VALUES (1, ‘IT’);
INSERT INTO department VALUES (2, ‘Sales’);

方法一、说下思路吧,两表内连接然后根据部门分组,用max函数查询薪资最高的,这种数据量比较多时,性能比较低

select c.deptname,c.name,max(salary) from (
select a.*,b.name as deptname from employee2 a inner join Department b on
a.DepartmentId=b.id
)as c GROUP BY c.deptname
1
2
3
4
方法二、官方解法,我觉得这个非常巧妙,一开始就通过子查询,拿到部门id,然后用内连接加上 in 得到各部门最高薪资,效率极高!

SELECT
Department.name AS 'Department',
Employee.name AS 'Employee',
Salary
FROM
Employee
JOIN
Department ON Employee.DepartmentId = Department.Id
WHERE
(Employee.DepartmentId , Salary) IN
( SELECT
DepartmentId, MAX(Salary)
FROM
Employee
GROUP BY DepartmentId
)

————————————————
版权声明:本文为CSDN博主「Jesscia ^_^」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/gubeichengxuyuan/article/details/122624729

精讲Mysql各种高难度Sql编写(一)的更多相关文章

  1. (高难度SQL)从产品表中找出相同前缀 (都云作者痴 谁解其中味)

    --期盼值 找出AA,3;PDST,3;QPL-,3;TP-,2; --基本表 create table tb_product( id number(9,0) primary key, name nv ...

  2. SQL语法精讲(包括建库、建表、建视图、查询、增加、删除、)

    SQL语法精讲(包括建库.建表.建视图.查询.增加.删除.修改) SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELE ...

  3. java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱

    java高级精讲之高并发抢红包~揭开Redis分布式集群与Lua神秘面纱 redis数据库 Redis企业集群高级应用精品教程[图灵学院] Redis权威指南 利用redis + lua解决抢红包高并 ...

  4. Mysql 索引精讲

    Mysql 索引精讲 开门见山,直接上图,下面的思维导图即是现在要讲的内容,可以先有个印象- 常见索引类型(实现层面) 索引种类(应用层面) 聚簇索引与非聚簇索引 覆盖索引 最佳索引使用策略 1.常见 ...

  5. 第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码

    第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码 scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开 ...

  6. 第三百四十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器

    第三百四十一节,Python分布式爬虫打造搜索引擎Scrapy精讲—编写spiders爬虫文件循环抓取内容—meta属性返回指定值给回调函数—Scrapy内置图片下载器 编写spiders爬虫文件循环 ...

  7. 微软BI SSIS 2012 ETL 控件与案例精讲课程学习方式与面试准备详解

    开篇介绍 微软BI SSIS 2012 ETL 控件与案例精讲 (http://www.hellobi.com/course/21) 课程从2014年9月开始准备,到2014年12月在 天善BI学院  ...

  8. 浅谈mysql配置优化和sql语句优化【转】

    做优化,我在这里引用淘宝系统分析师蒋江伟的一句话:只有勇于承担,才能让人有勇气,有承担自己的错误的勇气.有承担错误的勇气,就有去做事得勇气.无论做什么事,只要是对的,就要去做,勇敢去做.出了错误,承担 ...

  9. 《[MySQL技术内幕:SQL编程》读书笔记

    <[MySQL技术内幕:SQL编程>读书笔记 2019年3月31日23:12:11 严禁转载!!! <MySQL技术内幕:SQL编程>这本书是我比较喜欢的一位国内作者姜承尧, ...

  10. 小书MybatisPlus第7篇-代码生成器的原理精讲及使用方法

    本文是本系列文章的第七篇,前6篇访问地址如下: 小书MybatisPlus第1篇-整合SpringBoot快速开始增删改查 小书MybatisPlus第2篇-条件构造器的应用及总结 小书Mybatis ...

随机推荐

  1. ArkUI-X在Android平台动态化开发指南

    本文介绍如何在Android平台进行ArkUI-X动态化开发,包括动态化目录规则及约束. 适用场景 动态化主要包括两个典型场景: 场景1:框架动态化,为了降低应用ROM体积占用,及满足动态升级框架目的 ...

  2. ThreadLocal详解:线程私有变量的正确使用姿势

    ThreadLocal详解:线程私有变量的正确使用姿势 在多线程编程中,如何让每个线程都拥有自己独立的变量副本?ThreadLocal就像给每个线程分配了一个专属保险箱,解决了线程间数据冲突的问题.本 ...

  3. HyperWorks二维网格划分与单元连续性

    自动网格划分 HyperWorks中为零件定义几何曲面是创建零件壳单元网格的最佳方式.HyperMesh 创建二维网格最有效的方法是使用 Automesh 面板直接在零件的表面创建网格. Autome ...

  4. 基于 StarRocks 的指标平台查询加速方案

    项目背景 指标管理平台按指标查询类型可以划为落表指标和即席查询指标. 落表指标:可选择不同的维度生成多个结果表(每天提交任务写入结果表),对指标进行取数的时候会根据查询条件自动匹配最合适的结果表进行查 ...

  5. 在centos7等旧版linux上用国内源下载源码编译安装gcc并配置环境变量

    原文永久链接:https://forum.piwind.com/d/23-zai-centos7deng-jiu-ban-linuxshang-yong-guo-nei-yuan-xia-zai-yu ...

  6. vite V3.0.0 vite.config.ts 引入插件vite-plugin-vue-setup-extend-plus报错(vueSetupExtend不是一个函数)

    vite V3.0.0 vite.config.ts 引入插件报错(***** 不是函数) ·问题 #9414 ·Vitejs/Vite (github.com) 我的错误提示如下 ERROR fai ...

  7. Sql 日期时间各种操作

    select convert(varchar(10),getdate(),120) 输出格式:2008-02-27 00:25:13 SELECT CONVERT(char(19), getdate( ...

  8. [ThingsBoard] 2. 在源码上运行

    一.前言 本文基于 ThingsBoard 4.0.2 编写,对应提交Version set to 4.0.2(01c5ba7d37006e1f8a3492afbb3c67d017ca8dd3). 由 ...

  9. 前端开发系列100-小程序篇之UI组件库的使用和封装

    本文介绍微信小程序开发中常用的第三方UI组件库的基本使用流程和如何自定义组件. 1.0 第三方UI组件库的基本使用流程 通常,在使用第三方组件库之前首先需要通过代码的托管仓库和组件库文档来了解该组件库 ...

  10. leetcode 483 最小好二进制

    简介 对于困难的题目, 一般好像是不会一下子得出答案, 需要进行一定的数学分析, 然后才可以得出答案. 官房给出了数学的证明, 但是一般人数学早丢了, 还是二分法有用. 参考大神的, 思路简单来说就是 ...