在数据库操作中,除了需要查询数据,
有时候还需要对数据进行一些简单的处理,
用于优化数据显示效果等。
select的其他用法
select 除了可以选择列名外,还可以选择常量。
1 | select 3; # 3 |
upper、lower
分别用于将字符串转为大写和小写
ucase, lcase 分别也可以转大小写。
应用
当不知道查询内容的大小写时,可以统一转为大写/小写来匹配查询。
在 Oracle 数据库中区分大小写,Linux 的 MySQL 也区分
1 | select * from emp where upper(ename)='smith'; |
substr
用于截取字符串
用法
- substr(‘被截取的字符串’, 起始下标, 截取长度)
- substr(‘被截取的字符串’, 起始下标)
如果不写截取长度,就直接截取到尾部。
截取规则:
下标从 1 开始,-1 表示右侧第一个。
截取的方向永远往右边截取。
1 | select substr('abcd', -1, 2); # d |
上述 sql 只能得到 ‘d’,而不是 ‘cd’
应用
1 | select * from emp where substr(ename, 2, 1) = 'A'; |
选择 ename 第二个字符是 A 的行。
length、char_length
length 用于统计字符串的字节数
char_length 用于统计字符数
1 | select length('你好'); # 6 |
concat
用于拼接字符串,可以传入任意个参数。
1 | select concat('hello ', 'world'); # hello world |
mysql8之前可以采用 || 进行拼接。
‘hello ‘ || ‘world’ => ‘hello world’
trim
去除字符串前后空白字符。
1 | select trim(' a b c '); |
扩展
leading
1 | select trim(leading '0' from '000111'); |
去除前面的 0 字符。
trailing
1 | select trim(trailing '0' from '111000'); |
去除后面的 0 字符
both
1 | select trim(both 'x' from 'xx111xx'); |
去除前后的 x 字符
rand()
生成 0 到 1 之间的随机浮点数。
还有一种写法:rand(x)
通过传入一个值,保留本次随机数的值。
1 | select rand(1); # 0.918204912 |
这个 x 就相当于一个 key,每次获取同样的 x,得到的值都是一样的。
这个 x 应该是“种子”吧,如果种子相同得到的结果自然是一样的。
round(x)
四舍五入
1 | select round(3.5); # 4 |
指定保留的小数位
1 | select round(3.63, 1); #3.6 |
truncate(x, y)
只保留 y 个小数,剩下小数位舍弃
1 | select truncate(3.6666, 1); # 3.6 |
ceil(x)、floor(x)
ceil:向上取整
floor:向下取整
忽略四舍五入
1 | select ceil(4.7); # 5 |
1 | select floor(4.7); # 4 |
空处理
在 MySQL 和 Oracle 中,任何和 NULL 运算的结果都是 NULL;
ifnull(x, y)
如果 x 为 NULL,就用 y 代替
1 | select ename, sal, ((sal + ifnull(comm, 0)) * 12) as year_sal from emp; |
当 comm 为空时(员工没有津贴时),统一用 0 代替,避免运算结果为 NULL。
获取当前 datetime
now()
获取当前时间(select 执行的时间)
sysdate()
获取该函数执行的时间
底层应该是 now 直接被转化为当前时间,而 sysdate 按照程序执行顺序获取时间。
获取当前 date/time
current_date()
获取当前日期
current_time()
获取当前时间
可以省略括号()
获取单独的年月日时分秒
year(时间)
month(时间)
day(时间)
hour(时间)
minute(时间)
second(时间)
这里的时间可以是 now(),或者符合日期格式的字符串。
1 | select year('2024-07-12 22:26:31'); |
date_add
用于日期时间的运算
语法格式:
date_add(日期,interval expr 单位)
例如:
1 | select date_add('2020-10-14', interval 3 day); |
只提供“日期”,可以用“时分秒”等次级单位来增减间隔。
但是如果只提供“时分秒”,就无法用上一级的单位“年月日”来增减间隔了。
运算向下兼容。
参数介绍
日期:一个日期类型的数据或字符串
interval:固定写法,关键字
expr:指定一个具体的间隔量
可以为负数,效果和 date_sub 一致,表示往后退。
单位:
- 年月日
- 时分秒
- microsecond 微妙
- week 周
- quarter 一个季度(3个月)
复合单位
两个单位通过下划线组合在一起。
例如:
- year_month
- day_hour
- day_minute
- day_second
没有 month_day,不知道为什么。。
1 | select date_add('2020-10-14', interval '1,1' year_month); |
注意:expr 需用引号包裹,表示一个表达式。
date_format
用于日期格式化
语法格式:
date_format(日期, 格式字符串)
举例
1 | select date_format(now(), '%y-%m-%d %H:%i:%s'); |
参数介绍
日期:可以是日期类型数据或字符串
格式字符串:由“%”+代表年月日时间的字符,和其他分隔字符组成。
日期字符:
- Y / y:Y:四位完整的年份,y:完整年份的后两位数。
- m:月份
- d:日
- H:小时
- i:分钟
- s:秒
str_to_date
将字符串转为日期
语法格式:
str_to_date(日期, 格式字符串)
格式字符串与 date_format
一致。
例如:
1 | insert into t_student(name, birth) values('lisi', str_to_date('10/01/1999', '%m/%d/%Y')); |
或者直接输入遵循默认日期格式的字符串(%y-%m-%d %H:%i:%s)。
dayofweek, dayofmonth, dayofyear
分别给出目标日期对应一个星期,一个月,一年中的哪一天
语法格式:
dayofweek(日期)
同,可以是日期类型数据或者字符串。
1 | select dayofweek(now()); |
注:周日是一周的第一天
last_day
给出当前月份的最后一天的日期。
语法格式:
last_day(日期)
同,可以是日期类型数据或者字符串。
datediff, timediff
datediff:显示两个日期相差的天数。
timediff:求出两个日期相差的小时数,以时:分:秒的形式显示。
语法格式:
datediff(日期1, 日期2)
timediff(日期1, 日期2)
例如:
1 | select datediff('2000-10-10 10:10:10', '2000-10-9 10:10:10'); |
结果是以日期1比日期2晚 xx 时间计算的,前者时间晚于后者,结果为正数,反之为负数。
if
类似 Java 中的三目运算符。
语法格式:
if(条件, x, y)
条件符合返回 x,反之返回 y。
例如:
1 | select if(1<2, 1, 2); # 1 |
支持嵌套运算
当 job 为 SALESMAN 时薪水乘以 1.1 倍,为 MANAGER 时薪水乘以 2 倍,请给出结果。
1 | select sal, job, if(job='SALESMAN', sal*1.1, if(job='MANAGER', sal*2, sal)) as new_sal from emp; |
case…when…then…else…end
类似 Java 中的 switch
语法格式:
case 变量 when 匹配值 then 结果 else 结果 end
例如:(修改 if 嵌套)
:x:错误写法
1 | select sal, job, (case job |
:question: 为什么写成 job=’xxx’ 反而是 manager 的薪水乘以 1.1,salesman 的薪水乘以 2 了。
正确写法
1 | select sal, job, (case job |
结果和 if 嵌套写法一致。
建议先写好模板,然后一个一个条件填入
cast
用于类型转换
语法格式:
cast(值 as 数据类型)
数据类型:
- date:日期
- time:时间
- datetime:日期时间
- signed:有符号的 int 类型
- char:char(字符长度),字符。
- decimal:decimal(有效数字位,保留小数位),浮点数。
有效数字位包括小数位。
转化为 decimal 时如果指定的实际值超过了有效数字位,
会返回要求有效数字位的最大值。
如:将 ‘123.456’ 转为 decimal(3, 1) => 99.9
例如:将字符串转为浮点数
1 | select cast('000123.456' as decimal(4,1)); |
md5
单向加密算法,结果是一个固定长度 32 位的字符串。