数据准备:
create database mydb4;
use mydb4;
create table emp(
emp_id int primary key auto_increment comment '编号',
emp_name char(20) not null default '' comment '姓名',
salary decimal(10,2) not null default 0 comment '工资',
department char(20) not null default '' comment '部门'
);
insert into emp(emp_name,salary,department)
values('张晶晶',5000,'财务部'),('王飞飞',5800,'财务部'),('赵刚',6200,'财务部'),('刘小贝',5700,'人事部'),
('王大鹏',6700,'人事部'),('张小斐',5200,'人事部'),('刘云云',7500,'销售部'),('刘云鹏',7200,'销售部'),
('刘云鹏',7800,'销售部');
在MySQL中,聚合函数主要有:count、sum、min、max、avg、group_concat
group_concat()函数首先根据group by指定的列进行分组,并且用分隔符分隔,将同一个分组中的
值连接起来,返回一个字符串结果。
使用distinct可以排除重复值;
如果需要对结果中的值进行排序,可以使用order by子句;
separator是一个字符串值,默认为逗号。
-- 语法:group_concat([distinct] 字段名 [order by 排序字段 asc/desc] [separator '分隔符'])
-- 将所有员工的名字合并成一行
select group_concat(emp_name) from emp;
-- 指定分隔符合并
select department,group_concat(emp_name separator ';' ) from emp group by department;
-- 指定排序方式和分隔符
select department,group_concat(emp_name order by salary desc separator ';' ) from emp group by department;
函数 |
描述 |
实例 |
CHAR_LENGTH(s) |
返回字符串 s 的字符数 |
返回字符串 RUNOOB 的字符数 SELECT CHAR_LENGTH("RUNOOB") AS LengthOfString; |
CHARACTER_LENGTH(s) |
返回字符串 s 的字符数 |
返回字符串 RUNOOB 的字符数 SELECT CHARACTER_LENGTH ("RUNOOB") AS LengthOfString; |
CONCAT(s1,s2...sn) |
字符串 s1,s2 等多个字符串合并为一个字符串 |
合并多个字符串 SELECT CONCAT("SQL ", "Runoob ", "Gooogle ", "Facebook") AS ConcatenatedString; |
CONCAT_WS(x, s1,s2...sn) |
同 CONCAT(s1,s2,...) 函数,但是每个字符串之间要加上 x,x 可以是分隔符 |
合并多个字符串,并添加分隔符: SELECT CONCAT_WS ("-", "SQL", "Tutorial", "is", "fun!") AS ConcatenatedString; |
FIELD(s,s1,s2...) |
返回第一个字符串 s 在字符串列表(s1,s2...)中的位置 |
返回字符串 c 在列表值中的位置: SELECT FIELD("c", "a", "b", "c", "d", "e"); |
函数 |
描述 |
实例 |
LTRIM(s) |
去掉字符串 s 开始处的空格 |
去掉字符串 RUNOOB开始处的空格: SELECT LTRIM(" RUNOOB") AS LeftTrimmedString;-- RUNOOB |
MID(s,n,len) |
从字符串 s 的 n 位置截取长度为 len 的子字符串,同 SUBSTRING(s,n,len) |
从字符串 RUNOOB 中的第2个位置截取3个字符: SELECT MID("RUNOOB", 2, 3) AS ExtractString; -- UNO |
POSITION(s1 IN s) |
从字符串 s 中获取 s1 的开始位置 |
返回字符串 abc 中 b 的位置: SELECT POSITION('b' in 'abc') -- 2 |
REPLACE(s,s1,s2) |
将字符串 s2 替代字符串 s 中的字符串 s1 |
将字符串 abc 中的字符 a 替换为字符 x: SELECT REPLACE('abc','a','x') --xbc |
REVERSE(s) |
将字符串s的顺序反过来 |
将字符串 abc 的顺序反过来: SELECT REVERSE('abc') -- cba |
函数 |
描述 |
实例 |
RIGHT(s,n) |
返回字符串 s 的后 n 个字符 |
返回字符串 runoob 的后两个字符: SELECT RIGHT('runoob',2) -- ob |
RTRIM(s) |
去掉字符串 s 结尾处的空格 |
去掉字符串 RUNOOB 的末尾空格: SELECT RTRIM("RUNOOB ") AS RightTrimmedString; -- RUNOOB |
STRCMP(s1,s2) |
比较字符串 s1 和 s2,如果 s1 与 s2 相等返回 0 ,如果 s1>s2 返回 1,如果 s1 |
比较字符串: SELECT STRCMP("runoob", "runoob"); -- 0 |
SUBSTR(s, start, length) |
从字符串 s 的 start 位置截取长度为 length 的子字符串 |
从字符串 RUNOOB 中的第2个位置截取3个字符: SELECT SUBSTR("RUNOOB", 2, 3) AS ExtractString; -- UNO |
SUBSTRING(s, start, length) |
从字符串 s 的 start 位置截取长度为 length 的子字符串 |
从字符串 RUNOOB 中的第2个位置截取3个字符: SELECT SUBSTRING("RUNOOB", 2, 3) AS ExtractString; -- UNO |
函数 |
描述 |
实例 |
TRIM(s) |
去掉字符串 s 开始和结尾处的空格 |
去掉字符串 RUNOOB 的首尾空格: SELECT TRIM(' RUNOOB ') AS TrimmedString; |
UCASE(s) |
将字符串转换为大写 |
将字符串 runoob 转换为大写: SELECT UCASE("runoob"); -- RUNOOB |
UPPER(s) |
将字符串转换为大写 |
将字符串 runoob 转换为大写: SELECT UPPER("runoob"); -- RUNOOB |
LCASE(s) |
将字符串 s 的所有字母变成小写字母 |
字符串 RUNOOB 转换为小写: SELECT LCASE('RUNOOB') -- runoob |
LOWER(s) |
将字符串 s 的所有字母变成小写字母 |
字符串 RUNOOB 转换为小写: SELECT LOWER('RUNOOB') -- runoob |
-- 字符串函数
-- concat
select concat('Hello' , ' MySQL');
-- lower
select lower('Hello');
-- upper
select upper('Hello');
-- lpad
select lpad('01', 5, '-');
-- rpad
select rpad('01', 5, '-');
-- trim
select trim(' Hello MySQL ');
-- substring
select substring('Hello MySQL',1,5);
-- 案例: 由于业务需求变更,企业员工的工号,统一为5位数,目前不足5位数的全部在前面补0。比如: 1号员工的工号应该为00001。
update emp set workno = lpad(workno, 5, '0');
函数名 |
描述 |
实例 |
ABS(x) |
返回 x 的绝对值 |
返回 -1 的绝对值: SELECT ABS(-1) -- 返回1 |
CEIL(x) |
返回大于或等于 x 的最小整数 |
SELECT CEIL(1.5) -- 返回2 |
FLOOR(x) |
返回小于或等于 x 的最大整数 |
小于或等于 1.5 的整数: SELECT FLOOR(1.5) -- 返回1 |
GREATEST(expr1, expr2, expr3, ...) |
返回列表中的最大值 |
返回以下数字列表中的最大值: SELECT GREATEST(3, 12, 34, 8, 25); -- 34 返回以下字符串列表中的最大值: SELECT GREATEST("Google", "Runoob", "Apple"); -- Runoob |
LEAST(expr1, expr2, expr3, ...) |
返回列表中的最小值 |
返回以下数字列表中的最小值: SELECT LEAST(3, 12, 34, 8, 25); -- 3 返回以下字符串列表中的最小值: SELECT LEAST("Google", "Runoob", "Apple"); -- Apple |
函数名 |
描述 |
实例 |
MAX(expression) |
返回字段 expression 中的最大值 |
返回数据表 Products 中字段 Price 的最大值: SELECT MAX(Price) AS LargestPrice FROM Products; |
MIN(expression) |
返回字段 expression 中的最小值 |
返回数据表 Products 中字段 Price 的最小值: SELECT MIN(Price) AS MinPrice FROM Products; |
MOD(x,y) |
返回 x 除以 y 以后的余数 |
5 除于 2 的余数: SELECT MOD(5,2) -- 1 |
PI() |
返回圆周率(3.141593) |
SELECT PI() --3.141593 |
POW(x,y) |
返回 x 的 y 次方 |
2 的 3 次方: SELECT POW(2,3) -- 8 |
函数名 |
描述 |
实例 |
RAND() |
返回 0 到 1 的随机数 |
SELECT RAND() --0.93099315644334 |
ROUND(x) |
返回离 x 最近的整数(遵循四舍五入) |
SELECT ROUND(1.23456) --1 |
ROUND(x,y) |
返回指定位数的小数(遵循四舍五入) |
SELECT ROUND(1.23456,3) –1.235 |
TRUNCATE(x,y) |
返回数值 x 保留到小数点后 y 位的值(与 ROUND 最大的区别是不会进行四舍五入) |
SELECT TRUNCATE(1.23456,3) -- 1.234 |
-- 数值函数
-- ceil
select ceil(1.1);
-- floor
select floor(1.9);
-- mod
select mod(7,4);
-- rand
select rand();
-- round
select round(2.344,2);
-- 案例: 通过数据库的函数,生成一个六位数的随机验证码。
select lpad(round(rand()*1000000 , 0), 6, '0');
函数名 |
描述 |
实例 |
UNIX_TIMESTAMP() |
返回从1970-01-01 00:00:00到当前毫秒值 |
select UNIX_TIMESTAMP() -> 1632729059 |
UNIX_TIMESTAMP (DATE_STRING) |
将制定日期转为毫秒值时间戳 |
SELECT UNIX_TIMESTAMP ('2011-12-07 13:01:03'); |
FROM_UNIXTIME (BIGINT UNIXTIME [, STRING FORMAT]) |
将毫秒值时间戳转为指定格式日期 |
SELECT FROM_UNIXTIME(1598079966, '%Y-%m-%d %H:%i:%s'); (1598079966,'%Y-%m-%d %H:%i:%s'); -> 2020-08-22 15-06-06 |
CURDATE() |
返回当前日期 |
SELECT CURDATE(); -> 2018-09-19 |
CURRENT_DATE() |
返回当前日期 |
SELECT CURRENT_DATE(); -> 2018-09-19 |
函数名 |
描述 |
实例 |
CURRENT_TIME |
返回当前时间 |
SELECT CURRENT_TIME(); -> 19:59:02 |
CURTIME() |
返回当前时间 |
SELECT CURTIME(); -> 19:59:02 |
CURRENT_TIMESTAMP() |
返回当前日期和时间 |
SELECT CURRENT_TIMESTAMP() -> 2018-09-19 20:57:43 |
DATE() |
从日期或日期时间表达式中提取日期值 |
SELECT DATE("2017-06-15"); -> 2017-06-15 |
DATEDIFF(d1,d2) |
计算日期 d1->d2 之间相隔的天数 |
SELECT DATEDIFF('2001-01-01','2001-02-02') -> -32 |
函数名 |
描述 |
实例 |
TIMEDIFF(time1, time2) |
计算时间差值 |
SELECT TIMEDIFF ("13:10:11", "13:10:10"); -> 00:00:01 |
DATE_FORMAT(d,f) |
按表达式 f的要求显示日期 d |
SELECT DATE_FORMAT ('2011-11-11 11:11:11','%Y-%m-%d %r') -> 2011-11-11 11:11:11 AM |
STR_TO_DATE(string, format_mask) |
将字符串转变为日期 |
SELECT STR_TO_DATE ("August 10 2017", "%M %d %Y"); -> 2017-08-10 |
DATE_SUB(date,INTERVAL expr type) |
函数从日期减去指定的时间间隔。 |
Orders 表中 OrderDate 字段减去 2 天: SELECT OrderId,DATE_SUB (OrderDate,INTERVAL 2 DAY) AS OrderPayDate FROM Orders |
函数名 |
描述 |
实例 |
ADDDATE/DATE_ADD(d,INTERVAL expr type) |
计算起始日期 d 加上一个时间段后的日期,type 值可以是:
· MICROSECOND
· SECOND
· MINUTE
· HOUR
· DAY
· WEEK
· MONTH
· QUARTER
· YEAR
· DAY_MINUTE
· DAY_HOUR
· YEAR_MONTH
|
SELECT DATE_ADD("2017-06-15", INTERVAL 10 DAY); -> 2017-06-25 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL 15 MINUTE); -> 2017-06-15 09:49:21 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL -3 HOUR); ->2017-06-15 06:34:21 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL -3 HOUR); ->2017-04-15 |
函数名 |
描述 |
实例 |
DATE_ADD(d,INTERVAL expr type) |
计算起始日期 d 加上一个时间段后的日期,type 值可以是:
· SECOND_MICROSECOND
· MINUTE_MICROSECOND
· MINUTE_SECOND
· HOUR_MICROSECOND
· HOUR_SECOND
· HOUR_MINUTE
· DAY_MICROSECOND
· DAY_SECOND
· DAY_MINUTE
· DAY_HOUR
· YEAR_MONTH
|
SELECT DATE_ADD("2017-06-15", INTERVAL 10 DAY); -> 2017-06-25 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL 15 MINUTE); -> 2017-06-15 09:49:21 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL -3 HOUR); ->2017-06-15 06:34:21 SELECT DATE_ADD("2017-06-15 09:34:21", INTERVAL -3 HOUR); ->2017-04-15 |
EXTRACT(type FROM d) |
从日期 d 中获取指定的值,type 指定返回的值。
· MICROSECOND
· SECOND
· MINUTE
· HOUR
….. |
SELECT EXTRACT (MINUTE FROM '2011-11-11 11:11:11') -> 11 |
LAST_DAY(d) |
返回给给定日期的那一月份的最后一天 |
SELECT LAST_DAY("2017-06-20"); -> 2017-06-30 |
MAKEDATE(year, day-of-year) |
基于给定参数年份 year 和所在年中的天数序号 day-of-year 返回一个日期 |
SELECT MAKEDATE(2017, 3); -> 2017-01-03 |
函数名 |
描述 |
实例 |
YEAR(d) |
返回年份 |
SELECT YEAR("2017-06-15"); -> 2017 |
MONTH(d) |
返回日期d中的月份值,1 到 12 |
SELECT MONTH('2011-11-11 11:11:11') ->11 |
DAY(d) |
返回日期值 d 的日期部分 |
SELECT DAY("2017-06-15"); -> 15 |
HOUR(t) |
返回 t 中的小时值 |
SELECT HOUR('1:2:3') -> 1 |
MINUTE(t) |
返回 t 中的分钟值 |
SELECT MINUTE('1:2:3') -> 2 |
SECOND(t) |
返回 t 中的秒钟值 |
SELECT SECOND('1:2:3') -> 3 |
QUARTER(d) |
返回日期d是第几季节,返回 1 到 4 |
SELECT QUARTER('2011-11-11 11:11:11') -> 4 |
函数名 |
描述 |
实例 |
MONTHNAME(d) |
返回日期当中的月份名称,如 November |
SELECT MONTHNAME('2011-11-11 11:11:11') -> November |
MONTH(d) |
返回日期d中的月份值,1 到 12 |
SELECT MONTH('2011-11-11 11:11:11') ->11 |
DAYNAME(d) |
返回日期 d 是星期几,如 Monday,Tuesday |
SELECT DAYNAME('2011-11-11 11:11:11') ->Friday |
DAYOFMONTH(d) |
计算日期 d 是本月的第几天 |
SELECT DAYOFMONTH('2011-11-11 11:11:11') ->11 |
DAYOFWEEK(d) |
日期 d 今天是星期几,1 星期日,2 星期一,以此类推 |
SELECT DAYOFWEEK('2011-11-11 11:11:11') ->6 |
DAYOFYEAR(d) |
计算日期 d 是本年的第几天 |
SELECT DAYOFYEAR('2011-11-11 11:11:11') ->315 |
函数名 |
描述 |
实例 |
WEEK(d) |
计算日期 d 是本年的第几个星期,范围是 0 到 53 |
SELECT WEEK('2011-11-11 11:11:11') -> 45 |
WEEKDAY(d) |
日期 d 是星期几,0 表示星期一,1 表示星期二 |
SELECT WEEKDAY("2017-06-15"); -> 3 |
WEEKOFYEAR(d) |
计算日期 d 是本年的第几个星期,范围是 0 到 53 |
SELECT WEEKOFYEAR('2011-11-11 11:11:11') -> 45 |
YEARWEEK(date, mode) |
返回年份及第几周(0到53),mode 中 0 表示周天,1表示周一,以此类推 |
SELECT YEARWEEK("2017-06-15"); -> 201724 |
NOW() |
返回当前日期和时间 |
SELECT NOW() -> 2018-09-19 20:57:43 |
函数名 |
描述 |
实例 |
WEEK(d) |
计算日期 d 是本年的第几个星期,范围是 0 到 53 |
SELECT WEEK('2011-11-11 11:11:11') -> 45 |
WEEKDAY(d) |
日期 d 是星期几,0 表示星期一,1 表示星期二 |
SELECT WEEKDAY("2017-06-15"); -> 3 |
WEEKOFYEAR(d) |
计算日期 d 是本年的第几个星期,范围是 0 到 53 |
SELECT WEEKOFYEAR('2011-11-11 11:11:11') -> 45 |
YEARWEEK(date, mode) |
返回年份及第几周(0到53),mode 中 0 表示周天,1表示周一,以此类推 |
SELECT YEARWEEK("2017-06-15"); -> 201724 |
NOW() |
返回当前日期和时间 |
SELECT NOW() -> 2018-09-19 20:57:43 |
-- 日期函数
-- curdate()
select curdate();
-- curtime()
select curtime();
-- now()
select now();
-- YEAR , MONTH , DAY
select YEAR(now());
select MONTH(now());
select DAY(now());
-- date_add
select date_add(now(), INTERVAL 70 YEAR );
-- datediff
select datediff('2021-10-01', '2021-12-01');
-- 案例: 查询所有员工的入职天数,并根据入职天数倒序排序。
select name, datediff(curdate(), entrydate) as 'entrydays' from emp order by entrydays desc;
(日常美图时间)