分享10个高级sql写法
本文主要介绍博主在以往开发过程中,对于不同业务所对应的 sql 写法进行归纳总结而来。进而分享给大家。
- 本文所讲述 sql 语法都是基于 MySql 8.0+
- 博主github地址:http://github.com/wayn111 欢迎大家关注,点个star
一、ORDER BY FIELD() 自定义排序逻辑
MySql 中的排序 ORDER BY 除了可以用 ASC 和 DESC,还可以通过 ORDER BY FIELD(str,str1,...) 自定义字符串/数字来实现排序。这里用 order_diy 表举例,结构以及表数据展示:
ORDER BY FIELD(str,str1,...) 自定义排序sql如下:
SELECT * from order_diy ORDER BY FIELD(title,'九阴真经',
'降龙十八掌','九阴白骨爪','双手互博','桃花岛主',
'全真内功心法','蛤蟆功','销魂掌','灵白山少主');
查询结果如下:
如上,我们设置自定义排序字段为 title 字段,然后将我们自定义的排序结果跟在 title 后面。
二、CASE 表达式
case when then else end表达式功能非常强大可以帮助我们解决 if elseif else 这种问题,这里继续用 order_diy 表举例,假如我们想在 order_diy 表加一列 level 列,根据money 判断大于60就是高级,大于30就是中级,其余显示低级,sql 如下:
SELECT *,
case when money > 60 then '高级'
when money > 30 then '中级'
else '低级' END level
from order_diy;
查询结果:
三、EXISTS 用法
我猜大家在日常开发中,应该都对关键词 exists 用的比较少,估计使用 in 查询偏多。这里给大家介绍一下 exists 用法,引用官网文档:
可知 exists 后面是跟着一个子查询语句,它的作用是根据主查询的数据,每一行都放到子查询中做条件验证,根据验证结果(TRUE 或者 FALSE),TRUE的话该行数据就会保留,下面用 emp 表和 dept 表进行举例,表结构以及数据展示:
假如我们现在想找到 emp 表中 dept_name 与 dept表中 dept_name 对应不上的员工数据,也就是 emp 表第二行记录,sql 如下:
SELECT * from emp e where exists (
SELECT * from dept p
where e.dept_id = p.dept_id
and e.dept_name != p.dept_name
)
查询结果:
我们通过 exists 语法将外层 emp 表全部数据 放到子查询中与一一与 dept 表全部数据进行比较,只要有一行记录返回true。画个图展示主查询所有记录与子查询交互如下:
- 第一条记录与子查询比较时,全部返回 false,所以第一行不展示。
- 第二行记录与子查询比较时,发现
销售部门与 dept 表第二行销售部对应不上,返回 true,所以主查询该行记录会返回。 - 第二行以后记录执行结果同第一条。
四、GROUP_CONCAT(expr) 组连接函数
GROUP_CONCAT(expr) 组连接函数可以返回分组后指定字段的字符串连接形式,并且可以指定排序逻辑,以及连接字符串,默认为英文逗号连接。这里继续用 order_diy 表举例:sql 如下:
SELECT name, GROUP_CONCAT(title ORDER BY id desc SEPARATOR '-')
from order_diy GROUP BY name ORDER BY NULL;
查询结果:
如上我们通过 GROUP_CONCAT(title ORDER BY id desc SEPARATOR '-') 语句,指定分组连接 title 字段并按照 id 排序,设置连接字符串为 -。
五、自连接查询
自连接查询是 sql 语法里常用的一种写法,掌握了自连接的用法我们可以在 sql 层面轻松解决很多问题。这里用 tree 表举例,结构以及表数据展示:
tree 表中通过 pid 字段与 id 字段进行父子关联,假如现在有一个需求,我们想按照父子层级将 tree 表数据转换成 一级职位 二级职位 三级职位 三个列名进行展示,sql 如下:
SELECT t1.job_name '一级职位',
t2.job_name '二级职位',
t3.job_name '三级职位'
from tree t1 join tree t2 on t1.id = t2.pid
left join tree t3 on t2.id = t3.pid
where t1.pid = 0;
结果如下:
我们通过 tree t1 join tree t2 on t1.id = t2.pid 自连接展示 一级职位 二级职位,再用 left join tree t3 on t2.id = t3.pid 自连接展示 二级职位 三级职位,最后通过where 条件 t1.pid = 0过滤掉非一级职位的展示,完成这个需求。
六、更新 emp 表和 dept 表关联数据
这里继续使用上文提到的 emp 表和 dept 表,数据如下:
可以看到上述 emp 表中 jack 的部门名称与 dept 表实际不符合,现在我们想将 jack 的部门名称更新成 dept 表的正确数据,sql 如下:
update emp, dept set emp.dept_name = dept.dept_name
where emp.dept_id = dept.dept_id;
查询结果:
我们可以直接关联 emp 表和 dept 表并设置关联条件,然后更新 emp 表的 dept_name 为 dept 表的 dept_name。
七、ORDER BY 空值 NULL 排序
ORDER BY 字句中可以跟我们要排序的字段名称,但是当字段中存在 null 值时,会对我们的排序结果造成影响。我们可以通过 ORDER BY IF(ISNULL(title), 1, 0) 语法将 null 值转换成0或1,来达到将 null 值放到前面还是后面进行排序的效果。这里继续用 order_diy 表举例,sql 如下:
SELECT * FROM order_diy ORDER BY IF(ISNULL(title), 0, 1), money;
查询结果:
八、with rollup 分组统计数据的基础上再进行统计汇总
MySql 中可以使用 with rollup 在分组统计数据的基础上再进行统计汇总,即用来得到 group by 的汇总信息。这里继续用order_diy 表举例,sql 如下:
SELECT name, SUM(money) as money
FROM order_diy GROUP BY name WITH ROLLUP;
查询结果:
可以看到通过 GROUP BY name WITH ROLLUP 语句,查询结果最后一列显示了分组统计的汇总结果。但是 name 字段汇总后显示为 null,我们可以通过 COALESCE(value,...) 比较函数,返回第一个非空参数。
SELECT coalesce(name, '总金额') name, SUM(money) as money
FROM order_diy GROUP BY name WITH ROLLUP;
查询结果:
九、with as 提取临时表别名
with as 语法需要 MySql 8.0以上版本,它的作用主要是提取子查询,方便后续共用,更多情况下会用在数据分析的场景上。
如果一整句查询中多个子查询都需要使用同一个子查询的结果,那么就可以用with as,将共用的子查询提取出来,加个别名。后面查询语句可以直接用,对于大量复杂的SQL语句起到了很好的优化作用。这里继续用 order_diy 表举例,这里使用with as给出sql 如下:
-- 使用 with as
with t1 as (SELECT * from order_diy where money > 30),
t2 as (SELECT * from order_diy where money > 60)
SELECT * from t1
where t1.id not in (SELECT id from t2) and t1.name = '周伯通';
查询结果:
这个 sql 查询了 order_diy 表中 money 大于30且小于等于60之间并且 name 是周伯通的记录。
10、存在就更新,不存在就插入
MySql 中通过on duplicate key update语法来实现存在就更新,不存在就插入的逻辑。插入或者更新时,它会根据表中主键索引或者唯一索引进行判断,如果主键索引或者唯一索引有冲突,就会执行on duplicate key update后面的赋值语句。
这里通过 news 表举例,表结构和说数据展示,其中 news_code 字段有唯一索引:
添加sql:
-- 第一次执行添加语句
INSERT INTO `news` (`news_title`, `news_auth`, `news_code`)
VALUES ('新闻3', '小花', 'wx-0003')
on duplicate key update news_title = '新闻3';
-- 第二次执行修改语句
INSERT INTO `news` (`news_title`, `news_auth`, `news_code`)
VALUES ('新闻4', '小花', 'wx-0003')
on duplicate key update news_title = '新闻4';
结果如下:
总结
到这里,本文所分享的10个高级sql写法就全部介绍完了,希望对大家日常开发 sql 编写有所帮助,喜欢的朋友们可以点赞加关注。
公众号【waynblog】每周更新博主最新技术文章,欢迎大家关注
分享10个高级sql写法的更多相关文章
- 10款最佳SQL Server服务器监控工具
转自:http://server.51cto.com/sSecurity-587355.htm 推荐 | 10款最佳SQL Server服务器监控工具 服务器是网络中最重要的资源之一,SQL Serv ...
- 查询分页的几种Sql写法
查询分页的几种Sql写法 摘自:http://www.cnblogs.com/zcttxs/archive/2012/04/01/2429151.html 1.创建测试环境,(插入100万条数据大概耗 ...
- 高级SQL特性
SQL SQL 必知必会·笔记<20>高级SQL特性 摘要: 约束(constraint)就是管理如何插入或处理数据库数据的规则.DBMS通过在数据库表上施加约束来实施引用完整性.1. ...
- [转]高级SQL注入:混淆和绕过
############# [0×00] – 简介[0×01] – 过滤规避(Mysql)[0x01a] – 绕过函数和关键词的过滤[0x01b] – 绕过正则表达式过滤[0×02] – 常见绕过技术 ...
- DB2、ORACLE SQL写法的主要区别
DB2.ORACLE SQL写法的主要区别 说实话,ORACLE把国内的程序员惯坏了,代码中的SQL充斥着大量ORACLE特性,几乎没人知道ANSI的标准SQL是什么样子,导致程序脱离了ORACL ...
- 29.MySQL高级SQL语句
MySQL高级SQL语句 目录 MySQL高级SQL语句 创建两个表 SELECT DISTINCT WHERE AND OR IN BETWEEN 通配符 LIKE ORDER BY 函数 数学函数 ...
- 【原创 Hadoop&Spark 动手实践 10】Spark SQL 程序设计基础与动手实践(下)
[原创 Hadoop&Spark 动手实践 10]Spark SQL 程序设计基础与动手实践(下) 目标: 1. 深入理解Spark SQL 程序设计的原理 2. 通过简单的命令来验证Spar ...
- MySQL查询不区分大小写的sql写法
MySQL查询不区分大小写的sql写法 mysql查询默认是不区分大小写的 如: select * from some_table where str=‘abc'; select * from som ...
- 分享10个超实用的jQuery代码片段
来源:GBin1.com jQuery以其强大的功能和简单的使用成为了前端开发者最喜欢的JS类库,在这里我们分享一组实用的jQuery代码片段,希望大家喜欢! jQuery平滑回到顶端效果 $(doc ...
- 字段自动递增的数据库建表的SQL写法
数据库建表的SQL写法如下: 数据库建表的SQL写法如下: create table dataC( a int identity(1,2) primary key, b varchar(20)) ...
随机推荐
- 【已解决】nrm -g安装成功后不是全局应用(command not found: nrm)
本机情况: 服务器系统:CentOS 8.1 nodejs版本:20 问题描述: 在命令行执行命令,npm install -g nrm,全局安装nrm. 安装之后,执行nrm ls 报command ...
- 解决GET http://192.168.41.103:9528/sockjs-node/info?t=1678639328658 net::ERR_CONNECTION_TIMED_OUT
问题现象 解决办法 找到依赖/node_modules/sockjs-client/dist/sockjs.js注释掉下面的一行代码
- bash shell笔记整理——basename和dirname命令
bashname命令作用 去掉给定name的目录部分,如果指定了 SUFFIX, 就 同时去掉SUFFIX(后缀).具体看示例吧. bashname语法 Usage: basename NAME [S ...
- Javascript Ajax总结——其他跨域技术之Web Sockets
Web Sockets的目标是在一个单独的持久连接上提供全双工.双向通信.在Javascript中创建了Web Sockets之后,会有一个HTTP请求发送到浏览器以发起连接.在取得服务器响应后,建立 ...
- CentOS7 安装Python3.9以上版本时。编译报错,原因是openssl版本低
openssl-1.1.1安装 1.前因 python 导入clickhouse_driver需要import ssl和_ssl,报错 File"/home/oracle/python3/l ...
- Python 潮流周刊第 34 期(摘要)
本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...
- 实现两个 JSON 对象的对比
问题描述 在 Java 中,对于两个对象的对比,如果没有重写 equals 方法,那么将会默认使用 Object 默认的 equals 方法来比较两个对象.这种比较方式是通过比较两个对象的内存地址是否 ...
- Quartz.Net系列(十八):Quartz.Net中通过SQLServer实现对Job、Trigger持久化存储
1.介绍 RAMJobStore:一但关闭应用程序,数据全部丢失 Quartz中提供了两种方式配置数据库 JobStoreTx:带有事务的 JobStoreCMT:不带事务的
- TooKit助力开发者上云
本文分享自华为云社区<华为云Classroom赋能-TooKit助力开发者上云>,作者:华为云PaaS服务小智 . 对于资深程序员而言,IDE是必不可少的,它好比是剑客手中的宝剑,IDE帮 ...
- 华为云构建云原生DevSecOps平台,保障软件供应链全流程安全可信
摘要:面临网络安全挑战的大环境下,华为云构筑的云原生DevSecOps平台,打造了创新可控的安全服务,助力企业软件供应链全生命周期安全. 2022年8月13日,"2022中国DevOps社区 ...