内置函数上
1. 日期函数
1. 常用日期函数一览
日期函数主要干三件事:取时间、算时间、按时间筛选。
| 顺序 | 使用场景 | 函数名称(含参数与含义) | 说明 |
|---|
| 1 | 获取当前时间 | NOW() / CURRENT_TIMESTAMP() | 当前日期 + 时间 |
| | CURDATE() / CURRENT_DATE() | 当前日期 |
| | CURTIME() / CURRENT_TIME() | 当前时间 |
| 2 | 取日期 / 时间部分 | DATE(datetime)(取日期部分) | 常用于按天统计 |
| | TIME(datetime)(取时间部分) | 仅保留时分秒 |
| 3 | 从时间中取字段 | YEAR(datetime) / MONTH(datetime) / DAY(datetime) | 提取年/月/日 |
| | HOUR(datetime) / MINUTE(datetime) / SECOND(datetime) | 提取时/分/秒 |
| 4 | 时间加减计算 | DATE_ADD(date, INTERVAL n unit)(date + n 个时间单位) | 时间往后推 |
| | DATE_SUB(date, INTERVAL n unit)(date − n 个时间单位) | 时间往前推 |
| 5 | 时间差计算(天) | DATEDIFF(date1, date2)(date1 − date2,单位:天) | 只算日期,不管时分秒 |
| 6 | 时间差计算(精确) | TIMESTAMPDIFF(unit, start, end)(end − start,可指定单位) | 可算秒/分/小时/天/年 |
| 7 | 时间格式化(展示) | DATE_FORMAT(datetime, format)(按 format 输出字符串) | 仅影响显示 |
| 8 | 字符串转时间 | STR_TO_DATE(str, format)(按 format 解析字符串为时间) | 用于入库/比较 |
| 9 | 时间条件筛选(查询) | WHERE 时间字段 < / > / <= / >= DATE_ADD(...) / DATE_SUB(...) | 时间范围筛选 |
2. 获取当前时间的函数
1. NOW()(常用)
1 2 3 4 5 6
| mysql> select now(); + | now() | + | 2025-12-14 22:35:20 | +
|
用途:记录创建时间、更新时间。
1 2 3 4 5 6 7
| CREATE TABLE student ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(20) NOT NULL, age INT, create_time DATETIME DEFAULT NOW(), # 插入时默认用当前时间(等价于NOW()) update_time DATETIME DEFAULT NOW() ON UPDATE CURRENT_TIMESTAMP # 插入默认NOW(),更新自动刷新 );
|
2. CURRENT_TIMESTAMP(和 NOW 类似)
1 2 3 4 5 6
| mysql> select current_timestamp(); + | current_timestamp() | + | 2025-12-14 22:46:59 | +
|
3. CURDATE()、CURRENT_DATE()/CURTIME()、CURRENT_TIME()
1 2 3 4
| SELECT CURDATE(); # 当前日期 SELECT CURRENT_DATE() # 当前日期 SELECT CURTIME(); # 当前时间 SELECT CURRENT_TIME() # 当前时间
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| mysql> select current_date(); + | current_date() | + | 2025-12-14 | +
mysql> select current_time(); + | current_time() | + | 22:34:25 | +
mysql> select curdate(); + | curdate() | + | 2025-12-14 | +
mysql> select curtime(); + | curtime() | + | 22:42:30 | +
|
3. 从时间中“取字段”(常用)
参数统一为:日期/时间字段(DATETIME/DATE/TIME)、标准格式字符串(符合 YYYY-MM-DD/HH: MM: SS 的字符串)、日期函数结果(返回日期/时间的函数,相当于函数嵌套了)。
1. YEAR/MONTH/DAY(年/月/日)
1 2 3 4 5 6
| # 拆分订单创建时间的年、月、日 SELECT YEAR(created_at) AS 订单年份, # 提取年份 MONTH(created_at) AS 订单月份, # 提取月份 DAY(created_at) AS 订单日期 # 提取日期 FROM orders;
|
2. HOUR/MINUTE/SECOND(时/分/秒)
1 2 3 4 5 6
| # 拆分订单创建时间的时、分、秒 SELECT HOUR(created_at) AS 订单小时, # 提取小时(24小时制) MINUTE(created_at) AS 订单分钟, # 提取分 SECOND(created_at) AS 订单秒 # 提取秒 FROM orders;
|
3. DATE() / TIME()(高频)
1 2 3 4 5 6 7 8
| SELECT DATE(created_at), TIME(created_at) FROM orders;
mysql> select date(now()); + | date(now()) | + | 2025-12-14 | +
|
4. 时间计算函数(高频)
1. DATE_ADD() / DATE_SUB()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| # 给当前时间(now())加7天 → 结果是7天后的同一时间 mysql> select date_add(now(), interval 7 day); + | date_add(now(), interval 7 day) | + | 2025-12-22 13:18:36 | # 当前时间+7天的结果 +
# date_add传负数:给当前时间减10天 → 结果是10天前的同一时间 mysql> select date_add(now(), interval -10 day); + | date_add(now(), interval -10 day) | + | 2025-12-05 13:19:21 | # 当前时间-10天的结果 +
# 给当前时间减5天 → 结果是5天前的同一时间 mysql> select date_sub(now(),interval 5 day); + | date_sub(now(),interval 5 day) | + | 2025-12-10 13:20:12 | # 当前时间-5天的结果 +
# date_sub传负数:给当前时间加1年 → 结果是1年后的同一时间 mysql> select date_sub(now(),interval -1 year); + | date_sub(now(),interval -1 year) | + | 2026-12-15 13:20:50 | # 当前时间+1年的结果 +
|
常见单位:SECOND (秒)、MINUTE (分钟)、HOUR (小时)、DAY (天)、WEEK (周)、MONTH (月)、YEAR (年)。
2. DATEDIFF()(算天数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| # 说明:只算天,不管时分秒。 # datediff(日期1, 日期2):计算日期1 - 日期2的天数差(仅算日期,忽略时分秒) mysql> select datediff('2000.01.01',now()); + | datediff('2000.01.01',now()) | + | -9480 | # 2000-01-01 比 当前时间 早9480天,结果为负 +
# 计算当前时间 - 1999-09-09 的天数差(仅算日期,忽略时分秒) mysql> select datediff(now(), "1999-09-09"); + | datediff(now(), "1999-09-09") | + | 9594 | # 当前时间 比 1999-09-09 晚9594天,结果为正 +
|
3. TIMESTAMPDIFF()(更精确)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| # timestampdiff(单位, 起始时间, 结束时间):计算结束时间-起始时间的时间差,按指定单位返回 mysql> select timestampdiff(hour,'1999-09-09',now()); + | timestampdiff(hour,'1999-09-09',now()) | + | 230269 | # 1999-09-09到当前时间的小时差 +
mysql> select timestampdiff(day,'1999-09-09',now()); + | timestampdiff(day,'1999-09-09',now()) | + | 9594 | # 1999-09-09到当前时间的天数差 +
mysql> select timestampdiff(year,'1999-09-09',now()); + | timestampdiff(year,'1999-09-09',now()) | + | 26 | # 1999-09-09到当前时间的年数差 +
|
5. 格式化与解析时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| # date_format(时间, 格式化方式):自定义格式输出日期时间 mysql> select date_format(now(),"%Y-%m-%d"); + | date_format(now(),"%Y-%m-%d") | + | 2025-12-15 | +
mysql> select date_format(now(),"%Y-%M-%D"); + | date_format(now(),"%Y-%M-%D") | + | 2025-December-15th | +
mysql> select date_format(now(),"%y-%m-%d %h-%i-%s"); + | date_format(now(),"%y-%m-%d %h-%i-%s") | + | 25-12-15 01-40-29 | +
|
注意:小写多为精简数字格式(如 %y = 2 位年、%m = 数字月、%h = 12 小时制),大写多为完整/英文格式(如 %Y = 4 位年、%M = 英文月、%H = 24 小时制),仅秒无区别、分钟仅小写 %i。
2. STR_TO_DATE()(字符串转时间)
注意:字符串用 - 分隔年月日,格式符也必须写 %Y-%m-%d(用 -),如果字符串用 . 或 / 分隔,格式符需对应写成 %Y.%m.%d 或 %Y/%m/%d,否则解析失败返回 NULL。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| mysql> select str_to_date('2025-01-01 10:00:00','%Y-%m-%d %H:%i:%s'); + | str_to_date('2025-01-01 10:00:00','%Y-%m-%d %H:%i:%s') | + | 2025-01-01 10:00:00 | +
mysql> select str_to_date('2025/01/01 10:00:00','%Y-%m-%d %H:%i:%s'); + | str_to_date('2025/01/01 10:00:00','%Y-%m-%d %H:%i:%s') | + | NULL | +
mysql> select str_to_date('2025/01/01 10:00:00','%Y/%m/%d %H:%i:%s'); + | str_to_date('2025/01/01 10:00:00','%Y/%m/%d %H:%i:%s') | + | 2025-01-01 10:00:00 | +
|
6. 时间筛选
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
| # 创建t4表:含自增ID、评论内容、创建时间(默认当前时间)、更新时间(更新时自动刷新) mysql> create table t4( id int auto_increment primary key, content varchar(500) not null, create_time datetime default now(), update_time datetime default now() on update now());
# 插入2条测试数据:手动指定第一条的创建时间,第二条用当前时间 mysql> insert into t4(content,create_time) values ('我是小米里的大麦','2025-01-01 10:00:00'), ("喜欢就点个关注吧",now());
# 查看表中所有数据 mysql> select * from t4; + | id | content | create_time | update_time | + | 1 | 我是小米里的大麦 | 2025-01-01 10:00:00 | 2025-12-15 17:08:13 | | 2 | 喜欢就点个关注吧 | 2025-12-15 17:08:13 | 2025-12-15 17:08:13 | +
# 筛选创建时间≤2025-12-31的记录(两条都满足) mysql> select id,content,create_time from t4 where create_time<='2025-12-31'; + | id | content | create_time | + | 1 | 我是小米里的大麦 | 2025-01-01 10:00:00 | | 2 | 喜欢就点个关注吧 | 2025-12-15 17:08:13 | +
# 筛选创建时间≤2025-10-31的记录(仅第一条满足) mysql> select id,content,create_time from t4 where create_time<='2025-10-31'; + | id | content | create_time | + | 1 | 我是小米里的大麦 | 2025-01-01 10:00:00 | +
# 新增2条数据:仅传内容,创建/更新时间默认当前时间 mysql> insert into t4(content) values ("hhhh哈哈哈哈"),("今天是个悲伤的日子");
# 找出10分钟前创建的数据 mysql> select id,content,create_time,update_time from t4 where create_time<date_sub(now(),interval 10 minute); + | id | content | create_time | update_time | + | 1 | 我是小米里的大麦 | 2025-01-01 10:00:00 | 2025-12-15 17:08:13 | | 2 | 喜欢就点个关注吧 | 2025-12-15 17:08:13 | 2025-12-15 17:08:13 | +
# 找出10分钟更新的数据 mysql> select id,content,create_time,update_time from t4 where update_time<date_sub(now(),interval 10 minute); + | id | content | create_time | update_time | + | 1 | 我是小米里的大麦 | 2025-01-01 10:00:00 | 2025-12-15 17:08:13 | | 2 | 喜欢就点个关注吧 | 2025-12-15 17:08:13 | 2025-12-15 17:08:13 | +
# 找出最近10分钟更新的数据 mysql> select id,content,create_time,update_time from t4 where update_time>date_sub(now(),interval 10 minute); + | id | content | create_time | update_time | + | 3 | hhhh哈哈哈哈 | 2025-12-15 17:15:35 | 2025-12-15 17:15:35 | | 4 | 今天是个悲伤的日子 | 2025-12-15 17:15:35 | 2025-12-15 17:15:35 | +
# 找出创建时间晚于2025年3月10日的数据 mysql> select id,content,create_time from t4 where create_time > date_add('2024-10-10',interval 5 month); + | id | content | create_time | + | 2 | 喜欢就点个关注吧 | 2025-12-15 17:08:13 | | 3 | hhhh哈哈哈哈 | 2025-12-15 17:15:35 | | 4 | 今天是个悲伤的日子 | 2025-12-15 17:15:35 | +
# 找出创建时早于2025年3月10日的数据 mysql> select id,content,create_time from t4 where create_time < date_add('2024-10-10',interval 5 month); + | id | content | create_time | + | 1 | 我是小米里的大麦 | 2025-01-01 10:00:00 | +
|
2. 字符串函数
MySQL 常用字符串函数包括长度、拼接、截取、替换和查找等,展示和处理可以用,WHERE 中应避免对索引列使用函数以免索引失效。
| 使用场景 | 函数 | 参数解释 | 说明 / 返回结果 |
|---|
| 长度计算 | LENGTH(str) | str:要计算的字符串 | 返回 字节长度,中文通常 3 字节 |
| CHAR_LENGTH(str) | str:要计算的字符串 | 返回 字符个数(推荐使用) |
| 大小写转换 | UPPER(str) / UCASE(str) | str:原字符串 | 转成大写 |
| LOWER(str) / LCASE(str) | str:原字符串 | 转成小写 |
| 字符串拼接 | CONCAT(str1, str2, ...) | str1,str2...:按顺序拼接 | 只要有一个 NULL,结果就是 NULL |
| CONCAT_WS(sep, str1, str2, ...) | sep:分隔符;后面是要拼的字符串 | 自动忽略 NULL,推荐 |
| 截取子串 | SUBSTRING(str, start, len) | str:原字符串;start:从第几个字符开始(从 1 开始);len:取几个字符 | 返回截取后的字符串 |
| 左右截取 | LEFT(str, n) | n:从左边取 n 个字符 | 常用于取前缀 |
| RIGHT(str, n) | n:从右边取 n 个字符 | 常用于取后缀 |
| 去空格 | LTRIM(str) | 去掉字符串 左边 的空格 | 返回新字符串 |
| RTRIM(str) | 去掉字符串 右边 的空格 | |
| TRIM(str) | 去掉字符串 两端 的空格 | 常用 |
| 字符串替换 | REPLACE(str, old, new) | old:被替换的子串;new:新子串 | 全部匹配都会被替换 |
| 定点替换 | INSERT(str, pos, len, new_str) | pos:从第几个字符开始(从 1 开始);len:删掉几个字符;new_str:插入的新内容 | 先删再插 |
| 查找位置 | INSTR(str, sub) | sub:要找的子串 | 返回位置(从 1 开始),找不到返回 0 |
| LOCATE(sub, str) | 与 INSTR 一样,只是参数顺序相反 | |
| 字符串比较 | STRCMP(str1, str2) | 比较 str1 和 str2 的大小 | 相等 0,大于 1,小于 -1 |
| 模糊匹配 | LIKE | %:任意长度;_:一个字符 | 常用于前缀/模糊查询 |
| 字符集查看 | CHARSET(str) | 查看字符串当前使用的字符集 | 调试用,一般较少用 |
1. 字符串长度相关
1. LENGTH() —— 字节长度
1 2 3 4 5
| LENGTH(str)
mysql> select length(6); # 1 mysql> select length('abcd'); # 4 mysql> select length('你好'); # 6
|
注意:算的是 字节,中文通常 3 字节。
2. CHAR_LENGTH() —— 字符长度(推荐)
1 2 3 4 5
| CHAR_LENGTH(str)
mysql> select length(6); # 1 mysql> select length('abcd'); # 4 mysql> select length('你好'); # 2
|
2. 大小写转换(UCASE()、UPPER() / LCASE()、LOWER())
1 2 3 4 5 6 7
| UPPER(str)/UCASE(str) LOWER(str)/LCASE(str)
select ucase("abc"); # ABC select upper("abc"); # ABC select lcase("ABC"); # abc select lower("ABC"); # abc
|
3. 字符串拼接(常用)
1. CONCAT()
1 2 3 4
| CONCAT(str1, str2, ...)
select concat('hello','mysql'); # hellomysql select concat(NULL,"dashdhsadh","dasjdkhsa"); # NULL
|
注意:只要 有一个是 NULL → 结果就是 NULL。
2. CONCAT_WS()(更安全)
1 2 3 4
| CONCAT_WS(分隔符, str1, str2, ...)
select concat_ws(' ',"hellow","world"); # hellow world select concat_ws('-','2025',NULL,'11'); # 2025-11(自动忽略 NULL)
|
4. 子串相关
1. SUBSTRING()(常用)
1 2 3 4 5 6 7 8 9 10 11 12
| SUBSTRING(str, start, len) select substring('abcdefg',2,5); # bcdef(和C++的substr基本是一样的)
mysql> select substring('abcdefg',10); + | substring('abcdefg',10) | + | | +
mysql> select substring('abcdefg',0,10); # 输出同上,就是没有,空的! # 所以我们发现:只要起始位置/截取长度超出字符串范围,结果都是空字符串,没有区别!
|
2. LEFT() / RIGHT()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| LEFT(str, n) # LEFT(字符串, 要截取的个数):从最左边开始,截取x个字符 RIGHT(str, n) # RIGHT(字符串, 要截取的个数):从最右边开始,截取x个字符 # 哪怕超长度,也返回完整字符串,绝不空!只有截取个数=0时,才会空,这是和 SUBSTRING 最核心的区别(SUBSTRING 起始位超了就空) mysql> select left("abcd",4); + | left("abcd",4) | + | abcd | +
mysql> select left("abcd",6); + | left("abcd",6) | + | abcd | +
mysql> select right("abcd",3); + | right("abcd",3) | + | bcd | +
mysql> select right("abcd",6); + | right("abcd",6) | + | abcd | +
|
5. 去空格(LTRIM() / RTRIM() / TRIM())
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| LTRIM(str) # 去左空格 RTRIM(str) # 去右空格 TRIM(str) # 两边都去
# 1. LTRIM:只剪左边,右边空格保留 mysql> select ltrim(" abc 123 "); + | ltrim(" abc 123 ") | + | abc 123 | # 左边空没了,右边空还在 +
# 2. RTRIM:只剪右边,左边空格保留 mysql> select rtrim(" abc 123 "); + | rtrim(" abc 123 ") | + | abc 123 | # 右边空没了,左边空还在 +
# 3. TRIM:左右都剪,中间空格保留 mysql> select trim(" abc 123 "); + | trim(" abc 123 ") | + | abc 123 | # 左右空都没了,中间的“abc和123之间”的空还在 +
|
6. 字符串替换
1. REPLACE()
1 2 3 4 5 6 7 8 9
| REPLACE(str, old, new) REPLACE(要操作的字符串, 要替换掉的内容, 替换成的新内容)
mysql> select replace("hello world","world","mysql"); + | replace("hello world","world","mysql") | + | hello mysql | +
|
2. INSERT()(少用但要认识)
1 2 3 4 5 6 7 8 9
| INSERT(str, pos, len, new_str) INSERT(原始字符串, 起始位置, 要删除的字符数, 要插入的新内容)
mysql> select insert("hellow world",2,5,"xxxxxxxxxxx"); + | insert("hellow world",2,5,"xxxxxxxxxxx") | + | hxxxxxxxxxxx world | +
|
7. 查找位置(INSTR() / LOCATE())
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| INSTR(str, sub) # INSTR(被搜索的原始字符串, 要查找的子字符串) LOCATE(sub, str) # LOCATE(要查找的子字符串, 被搜索的原始字符串)
mysql> select instr("hellow","he"); + | instr("hellow","he") | + | 1 | +
mysql> select instr("hellow","hex"); + | instr("hellow","hex") | + | 0 | +
mysql> select locate("hex","hello"); + | locate("hex","hello") | + | 0 | +
mysql> select locate("he","hello"); + | locate("he","hello") | + | 1 | +
|
8. 字符串比较
1. STRCMP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| STRCMP(str1, str2)
mysql> select strcmp("abc","abc"); + | strcmp("abc","abc") | + | 0 | +
mysql> select strcmp("abc","ab"); + | strcmp("abc","ab") | + | 1 | +
mysql> select strcmp("ab","abc"); + | strcmp("ab","abc") | + | -1 | +
|
2. LIKE
准确来说 LIKE 不是字符串函数,他属于 SQL 匹配运算符(前面讲过),但这里提一下 = vs LIKE。
1 2
| WHERE name = 'tom'; # 精确 WHERE name LIKE 'tom'; # 等价但慢
|
9. 补充:CHARSET()(认识即可)
用于查看字符串使用的字符集
1 2 3 4 5 6 7 8
| CHARSET(str)
mysql> select charset("abc"); + | charset("abc") | + | utf8mb4 | +
|