【Mysql基础】二、函数和约束

608564A16E7D652E882914E830EE4050(1)

📚博客主页:代码探秘者-CSDN博客

🌈:最难不过坚持

✨专栏

🌈语言篇C语言\ C++Javase基础
🌈数据结构专栏数据结构
🌈算法专栏必备算法
🌈数据库专栏MysqlRedis
🌈必备篇

其他更新ing…

❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️

🙏作者水平有限,欢迎各位大佬指点,相互学习进步!

一、函数

字符串函数

常用函数:

函数功能
CONCAT(s1, s2, …, sn)字符串拼接,将s1, s2, …, sn拼接成一个字符串
LOWER(str)将字符串全部转为小写
UPPER(str)将字符串全部转为大写
LPAD(str, n, pad)左填充,用字符串pad对str的左边进行填充,达到n个字符串长度
RPAD(str, n, pad)右填充,用字符串pad对str的右边进行填充,达到n个字符串长度
TRIM(str)去掉字符串头部和尾部的空格
SUBSTRING(str, start, len)返回从字符串str从start位置起的len个长度的字符串
-- 拼接 CONCAT(s1, s2, …, sn)
select concat('Hello','MySQL');

-- 小写 LOWER(str)
select lower('I AM SPIDERMAN');

-- 大写 UPPER(str)
select upper('i am spiderman');

-- 左填充 LPAD(str, n, pad)
select lpad('hellomysql',20,0);

-- 右填充 RPAD(str, n, pad)
select rpad('hellomysql',20,0);

-- 去除空格 TRIM(str)
select trim('     do you wanna build a snowman  ');

-- 切片(起始索引为1) SUBSTRING(str, start, len)
select substr('howareuiamfinethanku',5,5);

-- 根据业务需求,企业员工的工号统一改为5位数,不足五位的前面用0补齐
UPDATE emp SET workno = lpad(workno,5,'0');

数值函数

常见函数:

函数功能
CEIL(x)向上取整
FLOOR(x)向下取整
MOD(x, y)返回x/y的模
RAND()返回0~1内的随机数
ROUND(x, y)求参数x的四舍五入值,保留y位小数
-- 数值函数

-- CEIL(x) answer=2
select ceil(1.8);

-- FLOOR(x) answer=1
select floor(1.8);

-- MOD(x, y) (取余数)
select mod(4,3);

-- RAND()
select rand();

-- ROUND(x, y) 求参数x的四舍五入值,保留y位小数 answer=2.90
select round(2.899,2);

-- 生成随机6位数
select rpad(round(rand()*1000000,0),6,0);

日期函数

常用函数:

函数功能
CURDATE()返回当前日期
CURTIME()返回当前时间
NOW()返回当前日期和时间
YEAR(date)获取指定date的年份
MONTH(date)获取指定date的月份
DAY(date)获取指定date的日期
DATE_ADD(date, INTERVAL expr type)返回一个日期/时间值加上一个时间间隔expr后的时间值
DATEDIFF(date1, date2)返回起始时间date1和结束时间date2之间的天数
-- CURDATE()
select curdate();

-- CURTIME()
select curtime();

-- NOW()
select now();

-- YEAR(date)-- MONTH(date)-- DAY(date)
select year(now());
select month(now());
select day(now());

-- DATE_ADD(date, INTERVAL expr type)
select date_add(now(),interval 10 day);

-- DATEDIFF(date1, date2)---date1-date2
select datediff(now(),'2000-04-01');

-- 查询所有员工的入职天数,并根据入职天数倒序排序
select name,datediff(now(),entrydate) from emp order by datediff(now(),entrydate) DESC;
select name,datediff(now(),entrydate) as entrydays from emp order by entrydays DESC;

流程函数

常用函数:

函数功能
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(value, t, f)--如果value为true,则返回t,否则返回f
select if(false,'ok','error');

-- IFNULL(value1, value2)--如果value1不为空,返回value1,否则返回value2
select ifnull(null,'error');
select ifnull('ok','error');


-- CASE [ expr ] WHEN [ val1 ] THEN [ res1 ] … ELSE [ default ] END
-- 如果expr的值等于val1,返回res1,… 否则返回default默认值
-- 需求:查询emp表的员工姓名和工作地址(上海/北京--->一线城市,其他--->二线城市)
select
       name,
       (case workaddress when '北京' then '一线城市' when '上海' then '一线城市' else '二线城市' end) as '工作城市'
from emp;


-- CASE WHEN [ val1 ] THEN [ res1 ] … ELSE [ default ] END
-- 如果val1为true,返回res1,… 否则返回default默认值
-- 统计班级成绩{ >=85优秀, >=60及格, else不及格 }
create table  score(
    id int comment 'ID',
    name varchar(20) comment '姓名',
    math int comment '数学',
    english int comment '英文',
    chinese int comment '语文'
) comment '学员成绩表';

insert into score(id, name, math, english, chinese)
values (1, 'Tom',67,88,95),(2,'Rose',23,66,90),(3,'Jack',56,98,76);

select
       id,
       name,
       (case when math >=85 then '优秀' when math >=60 then '及格' else '不及格'end) as math,
       (case when english >=85 then '优秀' when math >=60 then '及格' else '不及格'end) as english,
       (case when chinese >=85 then '优秀' when math >=60 then '及格' else '不及格'end) as chinese
from score;

条件函数

处理空值 coalesce

COALESCE(value1, value2, ..., valueN)
  • 参数:可以是任意数量的表达式,这些表达式可以是列名、常量或子查询结果。
  • 返回值:返回参数列表中的第一个非空值。如果所有参数都是 NULL,则返回 NULL。

用途

emp_idnamesalcomm
1Alice5000NULL
2Bob60001000
3CarolNULL2000
4Dave7000NULL

提供默认值:当某列可能包含 NULL 值时,可以用 COALESCE 提供一个默认值。

SELECT name, COALESCE(sal, 0) AS salary FROM employees;
  • 如果 sal 列的值是 NULL,则用 0 作为默认值
namesalary
Alice5000
Bob6000
Carol0
Dave7000

合并列:从多个列中选择第一个非空值

SELECT name, COALESCE(sal, comm, 0) AS total_compensation FROM employees;
  • 如果 sal 是 NULL,则检查 comm;如果 comm 也是 NULL,则用 0 作为默认值。
nametotal_compensation
Alice5000
Bob6000
Carol2000
Dave7000

处理空值:在计算或显示结果时避免 NULL 值

SELECT name, COALESCE(sal, 'N/A') AS salary FROM employees;
  • 如果 sal 列的值是 NULL,则用字符串 ‘N/A’ 作为默认值。
namesalary
Alice5000
Bob6000
CarolN/A
Dave7000

NULLIF

  • 比较两个表达式,如果它们相等,则返回 NULL;如果它们不相等,则返回第一个表达式的值。
NULLIF(expression1, expression2)
  1. 避免除以零:在计算中,如果分母可能为零,可以使用 NULLIF 来避免错误。
  2. 处理重复值:在比较两个值时,如果它们相等,可以返回 NULL。
  3. 数据清洗:在数据清洗过程中,处理某些特定的重复或异常值
SELECT COALESCE(NULLIF(sal, 0), 1) AS adjusted_sal FROM employees;

IFNULL

  • 返回其参数列表中的第一个非空值。如果所有参数都是 NULL,则返回 NULL。
IFNULL(expression1, expression2)
SELECT name, IFNULL(sal, 0) AS salary FROM employees;

解释:如果 sal 列的值是 NULL,则用 0 作为默认值。

小总结

在这里插入图片描述

注意:

在某些数据库(如 MySQL)中,

IFNULL和NULL 通常接受两个参数。

在标准 SQL 中,COALESCE 是更通用的函数,可以接受多个参数

CASE

  • 用于根据多个条件返回不同的值。它类似于其他编程语言中的 if-else 语句。
CASE
    WHEN condition1 THEN result1
    WHEN condition2 THEN result2
    ...
    ELSE default_result
END
SELECT name, sal, comm,
    CASE
        WHEN sal > 6000 THEN 'High'
        WHEN sal BETWEEN 5000 AND 6000 THEN 'Medium'
        ELSE 'Low'
    END AS salary_level
FROM employees;
namesalcommsalary_level
Alice5000NULLMedium
Bob60001000Medium
CarolNULL2000Low
Dave7000NULLHigh

IF

  • 根据一个条件返回两个值中的一个。
  • 类似JAVA和c语言的三目表达式
IF(condition, true_value, false_value)

案例:

SELECT name, sal, IF(sal > 5000, 'High', 'Low') AS salary_level FROM employees;
namesalsalary_level
Alice5000Low
Bob6000High
CarolNULLLow
Dave7000High

二、约束 Constraints

  1. 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。
  2. 目的:保证数据库中数据的正确、有效性和完整性。
  3. 分类:
约束描述关键字
非空约束限制该字段的数据不能为nullNOT NULL
唯一约束保证该字段的所有数据都是唯一、不重复的UNIQUE
主键约束主键是一行数据的唯一标识,要求非空且唯一PRIMARY KEY
默认约束保存数据时,如果未指定该字段的值,则采用默认值DEFAULT
检查约束(8.0.1版本后)保证字段值满足某一个条件CHECK
外键约束用来让两张图的数据之间建立连接,保证数据的一致性和完整性FOREIGN KEY

【注意】

约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。

常用约束

  • 非空约束:not null
  • 唯一约束:unique
  • 主键约束:primary key(自增)
  • 默认约束:defualt
  • 检查约束:check
  • 外键约束:foreign key

约束条件关键字
主键PRIMARY KEY
自动增长AUTO_INCREMENT
不为空NOT NULL
唯一UNIQUE
逻辑条件CHECK
默认值DEFAULT
create table user(
    id int primary key auto_increment comment 'id主键',
    name varchar(10) not null unique comment '姓名',
    age int check ( age > 0 and age <= 120 ) comment '年龄',
    status char(1) default '1' comment '状态',
    gender char(1) comment '性别'
) comment '用户表';

主键细节

  • 1.primary key不能重复而且不能为null
  • 2.一张表最多只能有一个主键但可以是复合主键
  • 3.主键的指定方式有两种
    • 直接在字段名后指定字段名primakry key
    • 在表定义最后写primary key(列名);
  • 4.使用desc表名,可以看到primary key的情况.

复合主键

复合主键(Composite Primary Key)是指由两个或多个字段共同组成的主键用来唯一标识数据库表中的每一行记录。简单来说,就是用多个列的组合来确保每条记录的唯一性。

为什么要用复合主键?

想象一下,你在管理一个图书馆的书籍。每本书都有一个ISBN号,理论上,ISBN号应该是唯一的。但是,假设有两本不同的书,它们恰好有相同的ISBN号(虽然在现实中这种情况几乎不可能发生,但为了举例,我们暂时这么假设)。在这种情况下,如果你只用ISBN号作为主键,数据库就会遇到问题,因为它不允许有重复的主键值。

为了解决这个问题,你可能会决定同时使用ISBN号和书籍的出版年份来唯一标识每本书。这样,即使两本书的ISBN号相同,它们的出版年份也不同,从而确保了每本书都能被唯一地识别。

举个例子 假设你有一个订单表,记录了客户下单的详细信息。每张订单可能包含多个商品,而且每个商品可能在不同的订单中重复出现。如果你只用商品ID作为主键,就无法区分同一个商品在不同订单中的记录。因此,你可能会选择使用“订单ID”和“商品ID”的组合作为复合主键。

CREATE TABLE OrderDetails (
    OrderID INT,
    ProductID INT,
    Quantity INT,
    Price DECIMAL(10, 2),
    PRIMARY KEY (OrderID, ProductID)	-- 复合主键
);

在这个例子中: OrderID 和 ProductID 共同组成了复合主键。 这意味着在同一个订单中,每个商品的组合(订单ID和商品ID的组合)必须是唯一的。 这样的设计确保了即使两个订单中都包含了同一个商品,它们也能被区分开来,因为每个订单的订单ID是不同的。

错误示范

CREATE TABLE OrderDetails (
    -- 不能有两个主键
    OrderID INT PRIMARY KEY,
    ProductID INT PRIMARY KEY,
    Quantity INT,
    Price DECIMAL(10, 2),
);

自增长细节

  • 1.一般来说自增长是和primary key配合使用的
  • 2.自增长也可以单独使用[但是需要配合一个unique]
  • 3.自增长修饰的字段为整数型的(虽然小数也可以但是非常非常少这样使用)
  • 4.自增长默认从1开始,你也可以通过如下命令修改
    • alter table 表名 auto_increment =新的开始值;
  • 5.如果你添加数据时,给自增长字段(列)指定的有值,则以指定的值为准,如果指定了自增长,一般来说,就按照自增长的规则来添加数据.

unique细节

  • 如果没有指定not null,则unique字段可以有多个null
  • 一张表可以有多个unigque字段

外键约束 foreign key

  • 外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性

外键必会细节

● foreign key(外键)—细节说明(创建小表演示)

  • 1.外键指向的表的字段,要求是primary key或者是unique
  • 2.表的类型是innodb,这样的表才支持外键
  • 3.外键字段的类型要和主键字段的类型一致(长度可以不同)
  • 4.外键字段的值,必须在主键字段中出现过,或者为null [前提是外键字段允许为null]
  • 5.一旦建立主外键的关系,数据不能随意删除了.

添加外键关联

创建表时添加
CREATE TABLE 表名(
    字段名 字段类型,
    ...
    [CONSTRAINT] [外键名称] FOREIGN KEY(外键字段名) 
    REFERENCES 主表(主表列名)
);

比如

CREATE TABLE parents (
    parent_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL
);

CREATE TABLE children (
    child_id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES parents(parent_id)
        ON DELETE CASCADE
        ON UPDATE CASCADE
);
  • 外键约束使用 FOREIGN KEY 关键字定义,并指定了 REFERENCES 子句来引用主键。
  • ON DELETE CASCADE ON UPDATE CASCADE 选项表示,当引用的主键被删除或更新时,相应的外键记录也会被级联删除或更新。(看情况也可以不要)
创建表后添加
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名);
  • 外键在创建后主表中的关联无法删除,这样保证了一致性和完整性

删除外键

ALTER TABLE 表名 DROP FOREIGN KEY 外键名;

案例

create table dept
(
    id   int auto_increment comment 'ID' primary key,
    name varchar(50) not null comment '部门名称'
) comment '部门表';

INSERT INTO dept (id, name)
VALUES (1, '研发部'),
       (2, '市场部'),
       (3, '财务部'),
       (4, '销售部'),
       (5, '总经办');

create table emp1
(
    id        int auto_increment comment 'ID' primary key,
    name      varchar(50) not null comment '姓名',
    age       int comment '年龄',
    job       varchar(20) comment '职位',
    salary    int comment '薪资',
    entrydate date comment '入职时间',
    managerid int comment '直属领导ID',
    dept_id   int comment '部门ID'
) comment '员工表';

INSERT INTO emp1 (id, name, age, job, salary, entrydate, managerid, dept_id)
VALUES (1, '金庸', 66, '总裁', 20000, '2000-01-01', null, 5),
       (2, '张无忌', 20, '项目经理', 12500, '2005-12-05', 1, 1),
       (3, '杨逍', 33, '开发', 8400, '2000-11-03', 2, 1),
       (4, '韦一笑', 48, '开 发', 11000, '2002-02-05', 2, 1),
       (5, '常遇春', 43, '开发', 10500, '2004-09-07', 3, 1),
       (6, '小昭', 19, '程 序员鼓励师', 6600, '2004-10-12', 2, 1);

-- 建立外键关联 ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名) REFERENCES 主表(主表列名);
alter table emp1 add constraint fk_emp1_dept_id foreign key (dept_id) references dept(id);

-- 删除外键 ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
alter table emp1 drop foreign key fk_emp1_dept_id;

删除/更新行为

行为说明
NO ACTION当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新(与RESTRICT一致)
RESTRICT当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新(与NO ACTION一致)
CASCADE当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则也删除/更新外键在子表中的记录
SET NULL当在父表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则设置子表中该外键值为null(要求该外键允许为null)
SET DEFAULT父表有变更时,子表将外键设为一个默认值(Innodb不支持)
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段) REFERENCES 主表名(主表字段名) 
  ON UPDATE 行为 ON DELETE 行为;
  
alter table emp1 add constraint fk_emp1_dept_id foreign key (dept_id) references dept(id) 
  on update CASCADE on delete CASCADE ;
  #CASCADE 的位置可以是上面四个
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码探秘者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值