MySQL中的一些非常实用的函数、语法
前言
我最近几年用MYSQL数据库挺多的,发现了一些非常有用的小玩意,今天拿出来分享到大家,希望对你会有所帮助。
1.group_concat
在我们平常的工作中,使用group by进行分组的场景,是非常多的。
比如想统计出用户表中,名称不同的用户的具体名称有哪些?
具体sql如下:
select name from `user`group by name;但如果想把name相同的code拼接在一起,放到另外一列中该怎么办呢?
答:使用group_concat函数。
例如:
select name,group_concat(code) from `user`group by name;执行结果:

使用group_concat函数,可以轻松的把分组后,name相同的数据拼接到一起,组成一个字符串,用逗号分隔。
2.char_length
有时候我们需要获取字符的长度,然后根据字符的长度进行排序。
MYSQL给我们提供了一些有用的函数,比如:char_length。
通过该函数就能获取字符长度。
获取字符长度并且排序的sql如下:
select * from brand where name like '%苏三%' order by char_length(name) asc limit 5;执行效果如图所示:

name字段使用关键字模糊查询之后,再使用char_length函数获取name字段的字符长度,然后按长度升序。
3.locate
有时候我们在查找某个关键字,比如:苏三,需要明确知道它在某个字符串中的位置时,该怎么办呢?
答:使用locate函数。
使用locate函数改造之后sql如下:
select * from brand where name like '%苏三%' order by char_length(name) asc, locate('苏三',name) asc limit 5,5;执行结果:

先按长度排序,小的排在前面。如果长度相同,则按关键字从左到右进行排序,越靠左的越排在前面。
除此之外,我们还可以使用:instr和position函数,它们的功能跟locate函数类似,在这里我就不一一介绍了,感兴趣的小伙伴可以找我私聊。
4.replace
我们经常会有替换字符串中部分内容的需求,比如:将字符串中的字符A替换成B。
这种情况就能使用replace函数。
例如:
update brand set name=REPLACE(name,'A','B') where id=1;这样就能轻松实现字符替换功能。
也能用该函数去掉前后空格:
update brand set name=REPLACE(name,' ','') where name like ' %';update brand set name=REPLACE(name,' ','') where name like '% ';使用该函数还能替换json格式的数据内容,真的非常有用。
5.now
时间是个好东西,用它可以快速缩小数据范围,我们经常有获取当前时间的需求。
在MYSQL中获取当前时间,可以使用now()函数,例如:
select now() from brand limit 1;返回结果为下面这样的:

它会包含年月日时分秒。
如果你还想返回毫秒,可以使用now(3),例如:
select now(3) from brand limit 1;返回结果为下面这样的:

使用起来非常方便好记。
6.insert into ... select
在工作中很多时候需要插入数据。
传统的插入数据的sql是这样的:
INSERT INTO `brand`(`id`, `code`, `name`, `edit_date`) VALUES (5, '108', '苏三', '2022-09-02 19:42:21');它主要是用于插入少量并且已经确定的数据。但如果有大批量的数据需要插入,特别是是需要插入的数据来源于,另外一张表或者多张表的结果集中。
这种情况下,使用传统的插入数据的方式,就有点束手无策了。
这时候就能使用MYSQL提供的:insert into ... select语法。
例如:
INSERT INTO `brand`(`id`, `code`, `name`, `edit_date`) select null,code,name,now(3) from `order` where code in ('004','005');这样就能将order表中的部分数据,非常轻松插入到brand表中。
7.insert into ... ignore
不知道你有没有遇到过这样的场景:在插入1000个品牌之前,需要先根据name,判断一下是否存在。如果存在,则不插入数据。如果不存在,才需要插入数据。
如果直接这样插入数据:
INSERT INTO `brand`(`id`, `code`, `name`, `edit_date`) VALUES (123, '108', '苏三', now(3));肯定不行,因为brand表的name字段创建了唯一索引,同时该表中已经有一条name等于苏三的数据了。
执行之后直接报错了:

这就需要在插入之前加一下判断。
当然很多人通过在sql语句后面拼接not exists语句,也能达到防止出现重复数据的目的,比如:
INSERT INTO `brand`(`id`, `code`, `name`, `edit_date`) select null,'108', '苏三',now(3) from dual where not exists (select * from `brand` where name='苏三');这条sql确实能够满足要求,但是总觉得有些麻烦。那么,有没有更简单的做法呢?
答:可以使用insert into ... ignore语法。
例如:
INSERT ignore INTO `brand`(`id`, `code`, `name`, `edit_date`) VALUES (123, '108', '苏三', now(3));这样改造之后,如果brand表中没有name为苏三的数据,则可以直接插入成功。
但如果brand表中已经存在name为苏三的数据了,则该sql语句也能正常执行,并不会报错。因为它会忽略异常,返回的执行结果影响行数为0,它不会重复插入数据。
8.select ... for update
MYSQL数据库自带了悲观锁,它是一种排它锁,根据锁的粒度从大到小分为:表锁、间隙锁和行锁。
在我们的实际业务场景中,有些情况并发量不太高,为了保证数据的正确性,使用悲观锁也可以。
比如:用户扣减积分,用户的操作并不集中。但也要考虑系统自动赠送积分的并发情况,所以有必要加悲观锁限制一下,防止出现积分加错的情况发生。
这时候就可以使用MYSQL中的select ... for update语法了。
例如:
begin;select * from `user` where id=1 for update;//业务逻辑处理update `user` set score=score-1 where id=1;commit;这样在一个事务中使用for update锁住一行记录,其他事务就不能在该事务提交之前,去更新那一行的数据。
需要注意的是for update前的id条件,必须是表的主键或者唯一索引,不然行锁可能会失效,有可能变成表锁。
9.on duplicate key update
通常情况下,我们在插入数据之前,一般会先查询一下,该数据是否存在。如果不存在,则插入数据。如果已存在,则不插入数据,而直接返回结果。
在没啥并发量的场景中,这种做法是没有什么问题的。但如果插入数据的请求,有一定的并发量,这种做法就可能会产生重复的数据。
当然防止重复数据的做法很多,比如:加唯一索引、加分布式锁等。
但这些方案,都没法做到让第二次请求也更新数据,它们一般会判断已经存在就直接返回了。
这种情况可以使用on duplicate key update语法。
该语法会在插入数据之前判断,如果主键或唯一索引不存在,则插入数据。如果主键或唯一索引存在,则执行更新操作。
具体需要更新的字段可以指定,例如:
INSERT INTO `brand`(`id`, `code`, `name`, `edit_date`) VALUES (123, '108', '苏三', now(3))on duplicate key update name='苏三',edit_date=now(3);这样一条语句就能轻松搞定需求,既不会产生重复数据,也能更新最新的数据。
但需要注意的是,在高并发的场景下使用on duplicate key update语法,可能会存在死锁的问题,所以要根据实际情况酌情使用。
10.show create table
有时候,我们想快速查看某张表的字段情况,通常会使用desc命令,比如:
desc `order`;结果如图所示:

确实能够看到order表中的字段名称、字段类型、字段长度、是否允许为空,是否主键、默认值等信息。
但看不到该表的索引信息,如果想看创建了哪些索引,该怎么办呢?
答:使用show index命令。
比如:
show index from `order`;也能查出该表所有的索引:

但查看字段和索引数据呈现方式,总觉得有点怪怪的,有没有一种更直观的方式?
答:这就需要使用show create table命令了。
例如:
show create table `order`;执行结果如图所示:

其中Table表示表名,Create Table就是我们需要看的建表信息,将数据展开:

我们能够看到非常完整的建表语句,表名、字段名、字段类型、字段长度、字符集、主键、索引、执行引擎等都能看到。
非常直接明了。
11.create table ... select
有时候,我们需要快速备份表。
通常情况下,可以分两步走:
创建一张临时表
将数据插入临时表
创建临时表可以使用命令:
create table order_2022121819 like `order`;创建成功之后,就会生成一张名称叫:order_2022121819,表结构跟order一模一样的新表,只是该表的数据为空而已。
接下来使用命令:
insert into order_2022121819 select * from `order`;执行之后就会将order表的数据插入到order_2022121819表中,也就是实现数据备份的功能。
但有没有命令,一个命令就能实现上面这两步的功能呢?
答:用create table ... select命令。
例如:
create table order_2022121820 select * from `order`;执行完之后,就会将order_2022121820表创建好,并且将order表中的数据自动插入到新创建的order_2022121820中。
一个命令就能轻松搞定表备份。
12.explain
很多时候,我们优化一条sql语句的性能,需要查看索引执行情况。
答:可以使用explain命令,查看mysql的执行计划,它会显示索引的使用情况。
例如:
explain select * from `order` where code='002';结果:

通过这几列可以判断索引使用情况,执行计划包含列的含义如下图所示:

说实话,sql语句没有走索引,排除没有建索引之外,最大的可能性是索引失效了。
下面说说索引失效的常见原因:

如果不是上面的这些原因,则需要再进一步排查一下其他原因。
13.show processlist
有些时候我们线上sql或者数据库出现了问题。比如出现了数据库连接过多问题,或者发现有一条sql语句的执行时间特别长。
这时候该怎么办呢?
答:我们可以使用show processlist命令查看当前线程执行情况。
如图所示:

从执行结果中,我们可以查看当前的连接状态,帮助识别出有问题的查询语句。
id 线程id
User 执行sql的账号
Host 执行sql的数据库的ip和端号
db 数据库名称
Command 执行命令,包括:Daemon、Query、Sleep等。
Time 执行sql所消耗的时间
State 执行状态
info 执行信息,里面可能包含sql信息。
如果发现了异常的sql语句,可以直接kill掉,确保数据库不会出现严重的问题。
14.mysqldump
有时候我们需要导出MYSQL表中的数据。
这种情况就可以使用mysqldump工具,该工具会将数据查出来,转换成insert语句,写入到某个文件中,相当于数据备份。
我们获取到该文件,然后执行相应的insert语句,就能创建相关的表,并且写入数据了,这就相当于数据还原。
mysqldump命令的语法为:mysqldump -h主机名 -P端口 -u用户名 -p密码 参数1,参数2.... > 文件名称.sql
备份远程数据库中的数据库:
mysqldump -h 192.22.25.226 -u root -p123456 dbname > backup.sql
相关文章:
MySQL中的一些非常实用的函数、语法
前言我最近几年用MYSQL数据库挺多的,发现了一些非常有用的小玩意,今天拿出来分享到大家,希望对你会有所帮助。1.group_concat在我们平常的工作中,使用group by进行分组的场景,是非常多的。比如想统计出用户表中&#x…...
RT-Thread移植到STM32F407
文章目录第一步:获取RT-Thread源码第二步:项目结构介绍第三步:拷贝示例代码到裸机工程第四步:删除无用文件第五步:修改工程目录结构第六步:添加工程文件路径第七步:编译第八步:修改配…...
VR全景到底有多全能?为何屡受关注?
告别两年的“冰封”时期,现在疫情放开已经有一段时间了,各个行业的市场和经济已经逐步回暖,但是疫情对广大群众造成的心理阴影还是迟迟未有退散。就拿去电影院看电影来说,以前看电影是看心情,现在看电影则是看环境&…...
剑指 Offer 30. 包含min函数的栈
摘要 剑指 Offer 30. 包含min函数的栈 一、栈解析 package Stock;import java.util.Stack;/*** Classname JZ30min函数栈* Description TODO* Date 2023/2/24 18:59* Created by xjl*/ public class JZ30min函数栈 {/*** description 最小栈的含义是每次从栈中获取的数据都是…...
stm32f407探索者开发板(二十二)——通用定时器基本原理讲解
文章目录一、三种定时器的区别二、通用定时器特点2.1 功能特点描述2.2 计数器模式三、通用定时器工作过程四、附一、三种定时器的区别 STM32F40x系列总共最多有14个定时器 三种(4)STM32定时器区别 二、通用定时器特点 2.1 功能特点描述 STM3 F4的通…...
cmake 入门三 常用变量和指令
cmake常用变量 一、cmake 变量引用的方式: 前面我们已经提到了,使用${}进行变量的引用。在IF 等语句中,是直接使用变量名而不通过${}取值 二,cmake 自定义变量的方式: 主要有隐式定义和显式定义两种,一…...
Linux基础命令-find搜索文件位置
文章目录 find 命令介绍 语法格式 命令基本参数 参考实例 1)在root/data目录下搜索*.txt的文件名 2)搜索一天以内最后修改时间的文件;并将文件删除 3)搜索777权限的文件 4)搜索一天之前变动的文件复制到test…...
获取浏览器硬件资源的媒体数据(拍照、录音、录频、屏幕共享)
目录一、window.navigator 对象包含有关访问者浏览器的信息取二、MediaDevices1.使用麦克风2.使用摄像头(和音频一样)3.拍照4.录屏三、MediaRecorder(录制,可录制音频视屏)一、window.navigator 对象包含有关访问者浏览器的信息取 <!DOCTYPE html>…...
Java入门教程||Java 日期时间||Java 正则表达式
Java 日期时间java.util包提供了Date类来封装当前的日期和时间。Date类提供两个构造函数来实例化Date对象。第一个构造函数使用当前日期和时间来初始化对象。Date( )第二个构造函数接收一个参数,该参数是从1970年1月1日起的毫秒数。Date(long millisec)Date对象创建…...
详解八大排序算法
文章目录前言排序算法插入排序直接插入排序:希尔排序(缩小增量排序)选择排序直接选择排序堆排序交换排序冒泡排序快速排序hoare版本挖坑法前后指针版本快速排序的非递归快速排序总结归并排序归并排序的非递归实现:计数排序排序算法复杂度及稳定性分析总结前言 本篇…...
python库streamlit学习笔记
什么是streamlit? Streamlit是一个免费的开源框架,用于快速构建和共享漂亮的机器学习和数据科学Web应用程序。它是一个基于Python的库,专为机器学习工程师设计。数据科学家或机器学习工程师不是网络开发人员,他们对花几周时间学习…...
C/C++开发,无可避免的内存管理(篇一)-约束好跳脱的内存
一、养成内存管理好习惯 1.1 养成动态对象创建、调用及释放好习惯 开发者手动接管内存分配时,必须处理这两个任务。分配原始内存时,必须在该内存中构造对象;在释放该内存之前,必须保证适当地撤销这些对象。如果你的项目是c项目&am…...
在React项目中引入字体文件并使用
一、背景 设计稿里某些文字所用的字体,系统默认不支持。 比如设计需要的这个字体:EmerlandRegular,即使在css里将文字字体设置为他们,实际效果也显示不出来。 二、现象及原因 1、样式 2、期待效果 3、实际效果 实际上是因为这个…...
STM32 CubeMX按键点灯
本文代码使用 HAL 库。 文章目录前言一、按键原理图二、CubeMX 创建工程三、代码讲解:1. GPIO的输入HAL库函数:2. 消抖:3. 详细代码四,实验现象:总结前言 我们继续讲解 stm32 f103,这篇文章将详细 为大家讲…...
2023链动2+1模式到底是什么?带你了解核心规则
2023链动21模式到底是什么?带你了解核心规则 2023-02-24 梦龙 大家好,我是你们熟悉而又陌生的好朋友梦龙,一个创业期的年轻人 传统的直销模式产品低价高卖,消费者难以接受。虽然直销省去了传统流通渠道的中间环节,但…...
【Java面试八股文宝典之基础篇】备战2023 查缺补漏 你越早准备 越早成功!!!——Day14
大家好,我是陶然同学,软件工程大三今年实习。认识我的朋友们知道,我是科班出身,学的还行,但是对面试掌握不够,所以我将用这100多天更新Java面试题🙃🙃。 不敢苟同,相信大…...
K8S篇-搭建kubenetes集群
安装环境 这里使用pve虚拟机搭建三台centos机器,搭建过程参考: Centos篇-Centos Minimal安装 此次安装硬件配置 CPU:2C 内存:2G 存储:64G 环境说明 操作系统:Centos 7.9 内核版本:6.2.0-1.el7.elrepo…...
文本生成图像简述4——扩散模型、自回归模型、生成对抗网络的对比调研
基于近年来图像处理和语言理解方面的技术突破,融合图像和文本处理的多模态任务获得了广泛的关注并取得了显著成功。 文本生成图像(text-to-image)是图像和文本处理的多模态任务的一项子任务,其根据给定文本生成符合描述的真实图像…...
财务共享建设,为什么需要电子影像系统?
某集团作为投资性集团公司,业务遍布全国20多个省市,控股公司200余家,业务范围涉及火电、供热、风电、天然气天然气、水务、铁路、港口、酒店、地产等20多个细分行业。 伴随着集团企业的快速发展,某集团在管理中面临“点多、面广、…...
「RISC-V Arch」SBI 规范解读(下)
第六章 定时器扩展(EID #0x54494D45"TIME") 这个定时器扩展取代了遗留定时器扩展(EID #0x00),并遵循 v0.2 中定义的调用规约。 6.1 函数:设置定时器(FID #0) struct sbi…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
sshd代码修改banner
sshd服务连接之后会收到字符串: SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢? 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头,…...
在Zenodo下载文件 用到googlecolab googledrive
方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!࿰…...
