MySQL--》如何在SQL中巧妙运用函数与约束,优化数据处理与验证?
目录
函数使用
字符串函数
数值函数
日期函数
流程函数
约束
函数使用
函数是指一段可以直接被另一段程序调用的程序或代码,在mysql当中有许多常见的内置函数,接下来开始对这些内置函数及其作用进行简单的讲解和使用:
字符串函数
mysql中内置了很多的字符串函数,常见的有如下几个:
函数 | 功能 |
---|---|
concat(s1,s2,s3...) | 字符串拼接,将s1,s2,s3...sn拼接成一个字符串 |
lower(str) | 将字符串str全部转为小写 |
upper(str) | 将字符串str全部转为大写 |
lpad(str,n,pad) | 左填充,用字符串pad对str的左边进行填充,达到n个字符串长度 |
rpad(str,n,pad) | 右填充,用字符串pad对str的右边进行填充,达到n个字符串长度 |
trim(str) | 去掉字符串头部和尾部的空格 |
substring(str,start,len) | 返回字符串str从start位置起的len个长度的字符串 |
接下来对上面的这些字符串函数一一进行一个演示,具体如下所示:
需求案例: 由于业务需求变更,企业员工的工号统一为5位数,目前不足5位数的全部在前面补0,比如1号员工的工号应该为00001,以下面这张员工表为例进行补0:
根据上面这张表想想我们该如何给工号前面补0呢?这里我们用到update函数,直接执行如下命令
update emp set workno = lpad(workno, 5, '0');
数值函数
mysql中内置了很多的数值函数,常见的有如下几个:
函数 | 功能 |
---|---|
ceil(x) | 向上取整 |
floor(x) | 向下取整 |
mod(x,y) | 返回x/y的模 |
rand() | 返回0~1内的随机数 |
round(x,y) | 求参数x的四舍五入的值,保留y位小数 |
接下来对上面的这些字符串函数一一进行一个演示,具体如下所示:
需求案例:通过数据库的函数,生成一个六位数的随机验证码,这个时候应该第一时间想到数值函数当中的生成随机数,但是其生成的是小数,如何操作呢?请往下看:
这里我们就借助数值函数的随机数,四舍五入以及左填充的方式实现,语句如下:
-- 生成六位随机数,包含小数
select rand()*1000000;
-- 生成六位随机数, 进行四舍五入保留0位小数
select round(rand()*1000000, 0);-- 生成六位随机数,可以出现小于6位的情况,如0.0012312,不足6位前面补0
select lpad(round(rand()*1000000, 0), 6, '0');
日期函数
mysql中内置了很多的日期函数,常见的有如下几个:
函数 | 功能 |
---|---|
curdate() | 返回当前日期 |
curtime() | 返回当前时间 |
now() | 返回当前日期和时间 |
year(date) | 获取指定date的年份 |
month(date) | 获取指定date的月份 |
day(date) | 获取指定date的日期 |
date_add(date, interval, expr type) | 返回应该日期/时间加上一个时间间隔expr后的时间值 |
datediff(date1, date2) | 返回起始时间date1和结束时间date2之间的天数 |
接下来对上面的这些日期函数一一进行一个演示,具体如下所示:
需求案例:查询所有员工的入职天数并根据入职天数倒序排序,这里我们使用如下这张表进行演示讲解:
想想应该怎么做呢?这里直接获取表中所有的员工姓名,其入职天数等于当前时间和入职时间的间隔,然后再以这个间隔进行降序排序即可,语句如下:
select name, datediff(curdate(), entrydate) as 'entryDays' from emp order by entryDays desc;
流程函数
流程函数也是很常用的一类函数,可以在sql语句中实现条件筛选从而提高语句的效率,常见语句如下:
函数 | 功能 |
---|---|
if(value, t, f) | 如果value为true,则返回t,否则返回f |
ifnull(value1, value2) | 如果value1不为空,则返回value1,否则返回value2 |
case when [val1] then [res1]...else [default] end | 如果val1为true,则返回res1,...,否则返回default默认值 |
case [expr] when [val1] then [res1]...else [default] end | 如果expr值为val1则返回res1,...否则返回default默认值 |
接下来对上面的这些流程函数一一进行一个演示,首先这里先演示一下if语句,具体如下所示:
接下来我们要实现对员工表当中的工作地址进行筛选,如果工作地址是北京/上海等地返回一线城市,否则返回二线城市,具体如下所示:
需求案例:根据一张学生表的语数外成绩,分别设置优秀、及格、不及格三种情况,如下:
我们先创建一张学生表,想想如何创建表并赋值数据呢?直接看如下语句:
create table students (id int comment '学号',name varchar(20) comment '姓名',chinese int comment '语文成绩',math int comment '数学成绩',english int comment '英语成绩'
) comment '学生表';
insert into students values (1, '张三', 80, 90, 75), (2, '李四', 15, 80, 90), (3, '王五', 70, 65, 40);
接下来我们开始对这张学生表的成绩进行分类,大于85优秀、大于60及格、小于60不及格:
约束
约束是作用于表中字段上的规则,用于限制存储在表中的数据的,是为了保证数据库中数据的正确、有效性和完整性,对于约束的分类主要分为以下几种:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制字段的数据不能为null | not null |
唯一约束 | 保证字段的所有数据唯一、不重复 | unique |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | primary key |
默认约束 | 保存数据如果未指定该字段的值则采用默认值 | default |
检查约束(8.0.16版本之后) | 保证字段值满足某一条件 | check |
外键约束 | 用来让两张表之间的数据建立连接,保证数据的一致性和完整性 | forelgn key |
如下我们可以根据下面这张表的需求完成表的结构创建:
这里我们直接执行如下命令并往表中插入一些数据:
-- 创建表
create table user (id int primary key auto_increment comment '主键',name varchar(10) not null unique comment '姓名',age int check ( age > 0 && age < 120 ) comment '年龄',status char(1) default '1' comment '状态',gender char(1) comment '性别'
) comment '用户表';
-- 插入数据
insert into user (name, age, status, gender) values ('张三', 20, '1', '男'), ('李四', 30, '1', '女' );
insert into user (name, age, status, gender) values ('王五', 40, '2', '男');
如下生成的表中自动生成主键并递增,大家可以尝试输入错误的年龄,重复的姓名试一试,数据库都是创建数据失败的:
当然我们也可以借助图形化工具datagrip,直接新建表格然后设置约束,如下所示:
外键约束:外键是用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性,如下可以通过员工表的dept_id字段与部门表建立连接:
在主外键关系当中我们把部门表称为父表(外键所关联的表称为父表),员工表称为子表(具有外键的表称为子表),当然有时候我们也可以将其称为主表和从表,目前下面这两张表在数据库层面并未建立外键关联,所以是无法保证数据的一致性和完整性的: