一、日期函数
now()
获取 当前日期+时间 (date + time)。sysdate()
获取 当前日期+时间。current_timestamp()
获取 当前时间戳。
SELECT now()
, sysdate()
, current_timestamp();
now()
在执行开始时,值就得到了。sysdate()
在函数执行时,动态得到值。
SELECT now()
, sysdate()
, current_timestamp()
, sleep(3)
, now()
, sysdate()
, current_timestamp();
1.创建日期
1. makdedate
SELECT makedate(2001,31);
SELECT makedate(2001,32);
2. maketime
SELECT maketime(12,15,30);
2. 日期格式化
1. date_format
SELECT date_format(now(), '%Y-%m-%d %T');
SELECT date_format(20130111191640, '%Y-%m-%d %H:%i:%s');
SELECT date_format('2008-08-08 22:23:01', '%Y/%m/%d %H:%i:%s');
2. time_format
SELECT time_format(now(), '%Y-%m-%d %T');
表达式 | 描述 |
---|
%Y | 代表 4 位的年份 |
%y | 代表 2 位的年份 |
%m | 代表月,格式为(01…12) |
%c | 代表月,格式为(1…12) |
%d | 代表月份中的天数,格式为(00…31) |
%e | 代表月份中的天数,格式为(0…31) |
%H | 代表小时,格式为(00…23) |
%k | 代表小时,格式为(0…23) |
%h | 代表小时,格式为(01…12) |
%I | 代表小时,格式为(01…12) |
%l | 代表小时,格式为(1…12) |
%i | 代表分钟,格式为(00…59) |
%r | 代表时间,格式为 12 小时制(hh:mm:ss [AP]M) |
%T | 代表时间,格式为 24 小时制(hh:mm:ss) |
%S | 代表秒,格式为(00…59) |
%s | 代表秒,格式为(00…59) |
3. 字符串转日期
1. str_to_date
SELECT str_to_date('2012-05-01 23:59:59', '%Y-%m-%d %T');
SELECT str_to_date('08/09/2008', '%m/%d/%Y');
SELECT str_to_date('08/09/08', '%m/%d/%y');
SELECT str_to_date('08.09.2008', '%m.%d.%Y');
SELECT str_to_date('08:09:30', '%h:%i:%s');
SELECT str_to_date('08.09.2008 08:09:30', '%m.%d.%Y %h:%i:%s');
4. 日期天数互转
1. to_days
SELECT to_days('0000-00-00');
SELECT to_days('2008-08-08');
2. from_days
SELECT from_days(733627);
5. 日期秒数互转
1. time_to_sec
select time_to_sec('01:00:05');
2. sec_to_time
select sec_to_time(3605);
6. 日期增加
1. date_add
set @dt = now();
select date_add(@dt, interval 1 year);
select date_add(@dt, interval 1 month);
select date_add(@dt, interval 1 day);
select date_add(@dt, interval 1 hour);
select date_add(@dt, interval 1 minute);
select date_add(@dt, interval 1 second);
select date_add(@dt, interval 1 microsecond);
select date_add(@dt, interval 1 quarter);
select date_add(@dt, interval 1 week);
select date_add(@dt, interval -1 day);
set @dt = '2008-08-09 12:12:33';
select date_add(@dt, interval '01:15:30' hour_second);
select date_add(@dt, interval '1 01:15:30' day_second);
2. adddate 加日期
3. addtime 加时间
select now()
, adddate(now(), 1)
, addtime(now(), 1);
7. 日期减少
1. date_sub 减去指定日期
select date_sub('1998-01-01 00:00:00', interval '1 1:1:1' day_second);
2. SUBDATE
SELECT NOW()
, SUBDATE(NOW(), INTERVAL 60 SECOND)
SELECT '2023-01-01'
, SUBDATE('2023-01-01', INTERVAL 60 SECOND)
SELECT NOW()
, SUBDATE(NOW(), INTERVAL 1000 MICROSECOND) AS a
, SUBDATE(NOW(), INTERVAL 1000 SECOND_MICROSECOND) AS b
, SUBDATE(NOW(), INTERVAL 1000 MINUTE_MICROSECOND) AS c
, SUBDATE(NOW(), INTERVAL 1000 HOUR_MICROSECOND) AS d
8. 日期间隔
1. datediff(date1,date2)
- 两个日期相减
date1 - date2
返回天数
select datediff('2008-08-08', '2008-08-01');
select datediff('2008-08-01', '2008-08-08');
2. timediff(time1,time2)
- 两个日期相减
time1 - time2
返回 time 差值 - 注意:timediff(time1,time2) 函数的 两个参数类型 必须相同
select timediff('2008-08-08 08:08:08', '2008-08-08 00:00:00');
select timediff('08:08:08', '00:00:00');
9. 日期 Unix 时间戳互转
1. unix_timestamp
select unix_timestamp();
select unix_timestamp('2008-08-08');
select unix_timestamp('2008-08-08 12:30:00');
2. from_unixtime
select from_unixtime(1218290027);
select from_unixtime(1218124800);
select from_unixtime(1218169800);
select from_unixtime(1218169800, '%Y %D %M %h:%i:%s %x');
10. 时间戳函数
1. timestamp 日期转时间戳
SELECT timestamp(now());
select timestamp('2008-08-08');
select timestamp('2008-08-08 08:00:00', '01:01:01');
select timestamp('2008-08-08 08:00:00', '10 01:01:01');
11. 时间戳增加
1. timestampadd(unit, interval, datetime_expr) 时间戳增加
select timestampadd(day, 1, '2008-08-08 08:00:00');
select date_add('2008-08-08 08:00:00', interval 1 day);
12. 时间戳减少
1. timestampdiff(unit, datetime_expr1, datetime_expr2) 时间戳减少
select timestampdiff(year,'2002-05-01','2001-01-01');
select timestampdiff(day ,'2002-05-01','2001-01-01');
select timestampdiff(hour,'2008-08-08 12:00:00','2008-08-08 00:00:00');
select datediff('2008-08-08 12:00:00', '2008-08-01 00:00:00');
13. 时区转换
1. convert_tz(dt, from_tz, to_tz)
select convert_tz('2008-08-08 12:00:00', '+08:00', '+00:00');
2. date_add、date_sub、timestampadd
- 时区转换,也可以通过
date_add
、date_sub
、timestampadd
来实现
select date_add('2008-08-08 12:00:00', interval -8 hour);
select date_sub('2008-08-08 12:00:00', interval 8 hour);
select timestampadd(hour, -8, '2008-08-08 12:00:00');
14. 根据生日计算年龄
set @birthday = STR_TO_DATE('2022-04-09 23:59:59', '%Y-%m-%d %T');
SELECT YEAR(FROM_DAYS(DATEDIFF(NOW(), @birthday))) AS age;
SELECT DATE_FORMAT(FROM_DAYS(TO_DAYS(NOW()) - TO_DAYS(@birthday)), '%Y') + 0 AS age;
set @birthday = STR_TO_DATE('2022-04-09 23:59:59', '%Y-%m-%d %T');
SELECT TIMESTAMPDIFF(YEAR, @birthday, CURDATE()) AS age;
set @birthday = STR_TO_DATE('2022-04-09 23:59:59', '%Y-%m-%d %T');
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(@birthday, '%Y') -
(DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(@birthday, '00-%m-%d')) AS age;
set @birthday = STR_TO_DATE('2022-04-08 23:59:59', '%Y-%m-%d %T');
SELECT FLOOR(DATEDIFF(CURDATE(), @birthday)/365.2422) AS age;
set @birthday = STR_TO_DATE('2022-04-07 23:59:59', '%Y-%m-%d %T');
SELECT YEAR(CURDATE()) - YEAR(@birthday) - (RIGHT(CURDATE(), 5) < RIGHT(@birthday, 5)) AS age;
set @birthday = STR_TO_DATE('2022-04-07 23:59:59', '%Y-%m-%d %T');
SELECT ROUND(DATEDIFF(CURDATE(), @birthday)/365.2422) AS age;
二、数值函数
1. sign
- X 的值为 负数、零、正数 时。
- 返回结果 依次为
-1
、0
、1
。
SELECT SIGN(100) sign
, SIGN(0) sign2
, SIGN(-100) sign3
, SIGN(null) sign4;
2. ROUND 四舍五入
SELECT ROUND(1.234, 2) AS round
, ROUND(1.235, 2) AS round2
3. CONVERT 转换
SELECT SUBSTR('20220206', 5, 2) AS month
, CONVERT(SUBSTR('20220206', 5, 2), UNSIGNED) AS month2;
三、字符函数
1. find_in_set
FIND_IN_SET(str,strlist);
:
查询 strlist 字段中包含 str 的结果。
返回的结果为 null、0 或 所在的位置(在 1 到 N 之间)。
- str:要查询的字符串(str 要包含一个逗号时,将无法正常运行)。
- strlist:字段名(参数以
,
分隔,如:1,2,6,8,10,22
)。
SELECT t.ids
, find_in_set(1, t.ids) AS position
FROM (
SELECT ',0,' ids
UNION ALL SELECT '1,' ids
UNION ALL SELECT '0,1,' ids
UNION ALL SELECT '-1,0,1' ids
UNION ALL SELECT '1,0,1' ids
UNION ALL SELECT 'null' ids
UNION ALL SELECT null ids
UNION ALL SELECT '' ids
) t

1. find_in_set
和 in
区别
- 如果 ids 是常量,使用
in
。 - 如果 ids 是变量,使用
find_in_set
。
2. find_in_set
和 like
区别
like
是广泛的模糊查询。find_in_set
是精确匹配,并且 字段值 之间用 ,
分开。
2. REPLACE 字符替换
SELECT REPLACE('123\n', '\n', '');
4. concat_ws 多个字符串拼接
SELECT concat_ws('_', '1', '2', 3, now())
FROM DUAL;
5. GROUP_CONCAT 结果集拼接
GROUP_CONCAT([DISTINCT] 'column1' [ORDER BY 'column2' [ASC|DESC]] ['SEPARATOR seq']);
SELECT dept_name
FROM sys_dept
WHERE dept_id IN ('8777', '8909', '8910');
SELECT GROUP_CONCAT(dept_name ORDER BY dept_id ASC SEPARATOR ',')
FROM sys_dept
WHERE dept_id IN ('8777', '8909', '8910');


6. 字符串截取
SELECT REPLACE(LTRIM(REPLACE(SUBSTRING_INDEX('2022-09', '-', -1), 0, ' ')), ' ', 0);
SELECT SUBSTRING_INDEX('2022-09', '-', -1);
SELECT REPLACE('09', 0, ' ');
SELECT REPLACE(' 9', ' ', 0);
SELECT LTRIM(' 9');
SELECT SUBSTR('2022-09', 6, 2);
SELECT CONVERT(SUBSTR('2022-09', 6, 2), UNSIGNED);
SELECT LEFT('1234', 2);
SELECT RIGHT('1234', 1);
SELECT SUBSTR('1234', 1, 2);
SELECT SUBSTR('1234', 2, 2);
SELECT LENGTH('1234');
SELECT LENGTH('张山');
SELECT CHAR_LENGTH('1234');
SELECT CHAR_LENGTH('张山');
7. 数据脱敏
SELECT user_name,
IF(
CHAR_LENGTH(user_name) > 2,
CONCAT(LEFT(user_name, 1), '*', RIGHT(user_name, 1)),
CONCAT('*', RIGHT(user_name, 1))
) AS userName2
FROM sys_user;
四、其他函数
1. ifnull(.,.)
- 如果
expr1
不是 NULL
,IFNULL()
返回 expr1
,否则它返回 expr2
。 IFNULL()
返回一个数字或字符串值,取决于它被使用的上下文环境。
SELECT IFNULL(1,0);
SELECT IFNULL(0,10);
SELECT IFNULL(1/0,10);
SELECT IFNULL(1/0,'yes');
2. if(.,.,.)
- 如果
expr1
是 TRUE
(expr1<>0
且 expr1<>NULL
),那么 IF()
返回 expr2
,否则它返回 expr3
。 IF()
返回一个数字或字符串值,取决于它被使用的上下文。
SELECT IF(1>2,2,3);
SELECT IF(1<2,'yes','no');
SELECT IF(strcmp('test','test1'),'yes','no');
SELECT IF(0.1,1,0);
SELECT IF(0.1<>0,1,0);
SELECT IF(0,1,2);
SELECT IF('qs' IS NOT NULL, 1, 0);
SELECT IF(2 = 2, 1, 0);
3. ON DUPLICATE KEY UPDATE—不存在新增,存在更新
- 当
INSERT
已经存在的记录时,执行 UPDATE
。
INSERT INTO demo (id, name) VALUES (1, '张三');
- 第一次插入
id=1
成功

INSERT INTO demo (id, name) VALUES (1, '李四');
- 第二次插入
id=1
失败
1062 - Duplicate entry ‘1’ for key ‘PRIMARY’
INSERT INTO demo (id, name) VALUES (1, '李四')
ON DUPLICATE KEY UPDATE
id = VALUES(id),
name = VALUES(name);
- 第三次
ON DUPLICATE KEY UPDATE
不存在新增,存在更新

INSERT INTO demo (id, name) VALUES
(1, '张山'), (2, '李四'), (3, '王五')
ON DUPLICATE KEY UPDATE
id = VALUES(id),
name = VALUES(name);
- 批量插入成功

INSERT INTO demo (id, name) VALUES
(1, '张山'), (2, '李四'), (3, '王五'), (4, '赵六')
ON DUPLICATE KEY UPDATE
id = VALUES(id),
name = 'wy';
- 批量修改指定值

INSERT INTO test (
province_code, city_code, area_code
) VALUES
<foreach collection="list" item="item" separator=",">
(
</foreach>
ON DUPLICATE KEY UPDATE
province_code= VALUES(province_code),
city_code= VALUES(city_code),
area_code= VALUES(area_code)
4. LAST_INSERT_ID()—上次插入的 ID
CREATE TABLE `qs_code` (
`code1` int(10) NOT NULL AUTO_INCREMENT COMMENT 'code1',
PRIMARY KEY (`code1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
ALTER TABLE dam_staff_code AUTO_INCREMENT = 1000000;
SELECT last_insert_id();
SELECT LAST_INSERT_ID();
SELECT @parentId := LAST_INSERT_ID();
SELECT @date := 20220714;
SELECT @rowNum := @rowNum + 1 AS serialNumber
5. nulls first 和 nulls last
SELECT sort
FROM user
ORDER BY sort nulls last
SELECT sort
FROM user
WHERE deleted = 0
ORDER BY sort IS NULL, sort
SELECT sort
FROM user
WHERE deleted = 0
ORDER BY sort IS NULL DESC, sort
SELECT 1 IS NULL, null IS NULL
`
0 1
`