MySQL的内置函数和复合查询

1.MySQL的内置函数

1.1日期函数

函数名称 描述 示例
current_date() 获取当前系统日期(格式:YYYY-MM-DD SELECT current_date();2026-05-23
current_time() 获取当前系统时间(格式:HH:MM:SS SELECT current_time();15:30:45
current_timestamp() 获取当前日期 + 时间(格式:YYYY-MM-DD HH:MM:SS SELECT current_timestamp();2026-05-23 15:30:45
date(datetime) 提取 datetime 参数中的日期部分 SELECT date('2026-05-23 15:30:45');2026-05-23
date_add(date, interval d_value type) 给日期 / 时间增加指定单位的数值 SELECT date_add('2026-05-23', interval 7 day);2026-05-30
date_sub(date, interval d_value type) 从日期 / 时间减去指定单位的数值 SELECT date_sub('2026-05-23', interval 1 month);2026-04-23
datediff(date1, date2) 计算两个日期的差值,结果单位为 SELECT datediff('2026-06-01', '2026-05-23');9
now() 获取当前日期 + 时间,和 current_timestamp() 效果一致 SELECT now();2026-05-23 15:30:45

interval 支持的单位 : 除了表格里提到的 yearminutesecondday,还支持 monthhourweek 等。 例如:interval 2 hour(2 小时)、interval 3 month(3 个月)。

datediff 注意事项 : 它的计算规则是 date1 - date2,结果为正数表示 date1date2 之后,负数则相反。

now() vs current_timestamp() : 两者在大部分场景下完全等价,now() 更简洁,日常开发中使用频率更高。

2.字符串函数

函数名称 描述 示例
charset(str) 返回字符串的字符集 SELECT charset('abc');utf8mb4
concat(string2 [, ...]) 连接多个字符串 SELECT concat('Hello', ' ', 'World');Hello World
instr(string, substring) 返回子串在字符串中首次出现的位置(从 1 开始计数,找不到返回 0) SELECT instr('abcdef', 'cd');3
ucase(string2) 将字符串全部转为大写(同 upper() SELECT ucase('hello');HELLO
lcase(string2) 将字符串全部转为小写(同 lower() SELECT lcase('HELLO');hello
left(string2, length) 从字符串左侧取指定长度的字符 SELECT left('abcdef', 3);abc
length(string) 返回字符串的字节长度(注意:不是字符数) SELECT length('你好');6(utf8mb4 下每个汉字占 3 字节)
replace(str, search_str, replace_str) 用指定字符串替换原字符串中的目标子串 SELECT replace('abcabc', 'a', 'x');xbcxbc
strcmp(string1, string2) 逐字符比较两字符串大小,返回 - 1/0/1(小于 / 等于 / 大于) SELECT strcmp('apple', 'banana');-1
substring(str, position [, length]) 从指定位置开始,截取指定长度的子串 SELECT substring('abcdef', 2, 3);bcd
ltrim(string) 去除字符串左侧的空格 SELECT ltrim(' abc');abc
rtrim(string) 去除字符串右侧的空格 SELECT rtrim('abc ');abc
trim(string) 去除字符串两侧的空格 SELECT trim(' abc ');abc

**charset (str)**返回字符串的字符集信息,例如 utf8mb4、gbk 等,常用于排查乱码问题。 该函数仅返回元数据,不改变原字符串内容。

**concat ()**支持多个参数拼接,参数类型会自动转为字符串。 若任意参数为 NULL,结果直接返回 NULL,需用 IFNULL 处理。 例如 SELECT concat (' 用户 ',IFNULL (name,' 匿名 ')) FROM user。

**instr (str,sub)**位置从 1 开始计数,找不到子串返回 0,区分大小写。 若要实现不区分大小写的查找,可配合 LOWER 或 UCASE 使用,例如 SELECT instr (LOWER (str),LOWER (sub))。

ucase () 与 lcase () ucase () 等同于 UPPER (),lcase () 等同于 LOWER (),两者可互换使用。 仅对英文字母生效,中文无大小写转换效果。

left (str,len) len 为正整数,代表截取字符数,不是字节数。 len 超过字符串长度时,返回原字符串。 若需从右侧截取,可使用 RIGHT (str,len),用法与 left 对称。

**length (str)**统计的是字节长度,受字符集影响,utf8mb4 下每个汉字占 3-4 字节。 如需统计字符数,应使用 char_length (str),不受字符集影响。 例如 SELECT length (' 你好 '),char_length (' 你好 '),结果为 6 和 2。

**replace (str,search_str,replace_str)**替换所有匹配的子串,不支持正则匹配。 若需正则替换,可使用 REGEXP_REPLACE(MySQL 8.0 及以上版本支持)。

**strcmp (str1,str2)**逐字符按 ASCII 码值比较,返回 - 1、0、1 分别表示小于、等于、大于。 仅支持字符串比较,数字会先转为字符串再比较,例如 strcmp ('10','2') 会返回 - 1,因为 '10' 的首字符 '1' 小于 '2'。

**substring (str,pos [,len])**pos 为 1 时表示从开头截取,为负数时从字符串末尾倒数计数。 省略 len 参数时,截取到字符串末尾。 也可写作 substr (str,pos [,len]),两者功能完全一致。 例如 SELECT substring ('abcd',-3,2),结果为 bc。

**ltrim ()、rtrim ()、trim ()**默认仅去除空格,也可指定去除其他字符。 trim 支持三种格式:trim (leading 'x' FROM str) 去除开头的 x,trim (trailing 'x' FROM str) 去除结尾的 x,trim (both 'x' FROM str) 去除两端的 x。 例如 SELECT trim (both 'x' FROM 'xxabcxx'),结果为 abc。

3.数字函数

函数名称 描述 示例
abs(number) 求绝对值 SELECT abs(-10)
bin(decimal_number) 十进制转二进制 SELECT bin(10)
hex(decimalNumber) 十进制转十六进制 SELECT hex(10)
conv(number,from_base,to_base) 任意进制转换 SELECT conv(10,10,2)
ceiling(number) 向上取整 SELECT ceiling(3.2)
floor(number) 向下取整 SELECT floor(3.8)
format(number,decimal_places) 数字格式化 SELECT format(1234.567,2)
rand() 生成随机数 SELECT rand()
mod(number,denominator) 取余数 SELECT mod(10,3)

abs 返回数值的绝对值,整数小数都支持 输入 null 结果为 null。bin 把十进制数字转成二进制字符串 小数会自动截断成整数 等价写法 conv (数字,10,2)。hex 十进制转十六进制 也可以把字符串转成十六进制编码。conv 支持 2-36 任意进制互相转换 第一个参数是待转换数 第二个是原进制 第三个是目标进制。ceiling 向上取整,别名 ceil 正数小数直接进一 负数小数往 0 方向取整。floor 向下取整 正数直接舍去小数 负数往负无穷方向取整。format 格式化数字,自动加千分位 四舍五入保留指定位数 结果是字符串,不能直接计算。rand 返回 0 到 1 之间的随机小数 固定种子会生成固定随机数。mod取模运算,等价于 % 结果符号和被除数一致。

1.4其他函数

函数名称 描述 示例
user() 查询当前登录用户 select user();
md5(str) 字符串 MD5 加密,返回 32 位字符串 select md5('admin');
database() 显示当前使用的数据库 select database();
password() MySQL 用户密码加密 select password('root');
ifnull(val1,val2) val1 为 null 返回 val2,否则返回 val1 select ifnull(null,'123');

user () 返回当前登录 MySQL 的账号和主机地址 格式为 用户名 @主机名。md5 (str) 固定生成 32 位长度的加密字符串 不可逆加密,常用于简单密码验证 相同字符串每次加密结果一致。database () 返回当前正在使用的数据库名称 没有选择数据库时返回 null 使用 use 数据库名 后可正常显示。password () MySQL 系统专用的密码加密函数 生成以 * 开头的 41 位字符串 MySQL 8.0 版本已不推荐使用。ifnull (val1,val2) 专门处理 null 值的判断函数 只有两个参数,必须成对使用 val2 可以是数字、字符串、字段名 常用在查询结果中替换 null 为默认值。

2.复合查询

2.1多表查询

多表查询就是在支持的select语句的from后加多个表而言,注意表名之间用逗号隔开。查询的行要注意表之间是否重复,如果重复要表明是哪个表的行。

复制代码
Create Table: CREATE TABLE `EMP` (
  `EMPNO` int NOT NULL COMMENT '员工编号',
  `ENAME` varchar(20) DEFAULT NULL COMMENT '员工姓名',
  `JOB` varchar(20) DEFAULT NULL COMMENT '职位',
  `MGR` int DEFAULT NULL COMMENT '上级编号',
  `HIREDATE` date DEFAULT NULL COMMENT '入职日期',
  `SAL` decimal(7,2) DEFAULT NULL COMMENT '月薪',
  `COMM` decimal(7,2) DEFAULT NULL COMMENT '奖金',
  `DEPTNO` int DEFAULT NULL COMMENT '部门编号',
  PRIMARY KEY (`EMPNO`),
  KEY `DEPTNO` (`DEPTNO`),
  CONSTRAINT `EMP_ibfk_1` FOREIGN KEY (`DEPTNO`) REFERENCES `DEPT` (`DEPTNO`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
显示部门号为10的部门名,员工名和工资
select ename, sal,dname from EMP, DEPT where EMP.deptno=DEPT.deptno and
DEPT.deptno = 10;
显示各个员工的姓名,工资,及工资级别
select ename, sal, grade from EMP, SALGRADE where EMP.sal between losal and
hisal;

2.2自链接

自连接是指在同一张表连接查询。

复制代码
//显示员工 FORD 的上级领导的编号和姓名(mgr 是员工领导的编号 --empno)使用子查询
select empno,ename from emp where emp.empno=(select mgr from emp where ename='FORD');
//使用多表查询(自连接)
-- 使用到表的别名
-- from emp leader, emp worker,给自己的表起别名,因为要先做笛卡尔积,所以别名可以先识别
select leader.empno,leader.ename from emp leader, emp worker where leader.empno = worker.mgr and worker.ename='FORD';

2.3子查询

子查询是指嵌套在其他select语句的select语句,也叫嵌套查询。

2.3.1单行查询

返回一行记录的子查询。

复制代码
显示 SMITH 同一部门的员工
select * from EMP where deptno=(select deptno from EMP where ename='SMITH');

2.3.2多行子查询

返回多行记录的子查询。可以使用关键字:in: 在多个结果里匹配任意一个 就满足条件 子查询返回多行时用 例子:岗位是 10 部门里任意一种就行。all: 必须大于 / 小于所有结果 比全部都高 / 都低才满足 例子:工资比 30 部门所有人都高。any: 满足大于 / 小于任意一个结果 比其中一个高 / 低就行 例子:工资比 30 部门任意一个人高

2.4合并查询

合并查询用于把多个 select 结果合在一起 ,用两个关键字:unionunion all。

union :功能:合并两个结果集,自动去掉重复行 适用场景:既要合并,又要去重。

案例:找出工资 > 2500 或者 职位是 MANAGER 的人。

复制代码
select ename,sal,job from EMP where sal>2500
union
select ename,sal,job from EMP where job='MANAGER';

union all :功能:合并两个结果集,不去重,保留所有记录 。适用场景:只合并,不做去重,效率更高 。

案例:同上,不去重。

复制代码
select ename,sal,job from EMP where sal>2500
union all
select ename,sal,job from EMP where job='MANAGER';

两个关键字区别:union:合并 + 去重 + 排序 union all:只合并,不去重,执行更快

复制代码
-- 高于部门平均工资
select ename,deptno,sal,format(asal,2) from EMP,
(select avg(sal) asal,deptno dt from EMP group by deptno) tmp
where EMP.sal>tmp.asal and EMP.deptno=tmp.dt;

-- 各部门最高工资
select EMP.ename,EMP.sal,EMP.deptno,ms from EMP,
(select max(sal) ms,deptno from EMP group by deptno) tmp
where EMP.deptno=tmp.deptno and EMP.sal=tmp.ms;

-- 部门人数统计
select DEPT.deptno,dname,mycnt,loc from DEPT,
(select count(*) mycnt,deptno from EMP group by deptno) tmp
where DEPT.deptno=tmp.deptno;
相关推荐
罗超驿10 小时前
21.jdbc 学习笔记:从原理到实践的全流程梳理
java·数据库·mysql·面试
fengxin_rou11 小时前
【MySQL SQL 执行全链路剖析】:执行计划、慢查询与经典场景优化指南
数据库·sql·mysql
fengxin_rou11 小时前
【Spring AI 集成 DeepSeek 实现 AI 摘要与 RAG 问答】:从原理到落地实践
数据库·mysql·rag·deepseek
绝知此事21 小时前
【算法突围 02】树形结构与数据库索引:树形结构与数据库索引:从 BST 到 B+ 树的演化与 MySQL 优化
数据库·mysql·算法·面试·b+树
muddjsv1 天前
SQL 最常用技能详解与实战示例
数据库·sql·mysql
ᰔᩚ. 一怀明月ꦿ1 天前
MySQL 学习目标
学习·mysql·adb
他们叫我阿冠1 天前
Day4学习--MySQL高级
数据库·学习·mysql
罗超驿1 天前
20.MySQL事务隔离级别示例详解(脏读、不可重复读、幻读)
java·数据库·mysql·面试
独泪了无痕1 天前
MySQL中 JSON 数据类型使用指南
mysql