爱站网长尾词挖掘,最近发生的热点新闻,wordpress关于页面,开发者头条表的增删改查#xff08;进阶#xff09; 一. 数据库约束1. 约束类型2. NULL约束3. UNIQUE#xff1a;唯一约束4. DEFAULT#xff1a;默认值约束5. PRIMARY KEY#xff1a;主键约束6. FOREIGN KEY#xff1a;外键约束7. CHECK约束 二. 表的设计1. 一对一2. 一对多3. 多对… 表的增删改查进阶 一. 数据库约束1. 约束类型2. NULL约束3. UNIQUE唯一约束4. DEFAULT默认值约束5. PRIMARY KEY主键约束6. FOREIGN KEY外键约束7. CHECK约束 二. 表的设计1. 一对一2. 一对多3. 多对多 三. 新增四. 查询1. 聚合查询1. 聚合函数2. GROUP BY子句3. HAVING 2. 联合查询1. 内连接2. 外连接3. 自连接4. 自然连接5. 子查询6. 合并查询 五. 删除 一. 数据库约束
1. 约束类型
NOT NULL - 指示某列不能存储 NULL 值。 UNIQUE - 保证某列的每行必须有唯一的值。 DEFAULT - 规定没有给列赋值时的默认值。 PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列或两个列多个列的结合有唯一标识有助于更容易更快速地找到表中的一个特定的记录。 FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。 CHECK - 保证列中的值符合指定的条件。对于 MySQL 数据库对 CHECK 子句进行分析但是忽略 CHECK 子句。
2. NULL约束
创建表时可以指定某列不为空
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (id INT NOT NULL,sn INT,name VARCHAR(20),qq_mail VARCHAR(20)
);3. UNIQUE唯一约束
指定 sn 列为唯一的、不重复的
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (id INT NOT NULL,sn INT UNIQUE,name VARCHAR(20),qq_mail VARCHAR(20)
);修改、插入数据时会先查看数据是否已经存在 已存在的话插入\修改失败 否则插入\修改成功
4. DEFAULT默认值约束
指定插入数据时name 列为空默认值 unkown
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (id INT NOT NULL,sn INT UNIQUE,name VARCHAR(20) DEFAULT unkown,qq_mail VARCHAR(20)
);5. PRIMARY KEY主键约束
指定id列为主键
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (id INT NOT NULL PRIMARY KEY,sn INT UNIQUE,name VARCHAR(20) DEFAULT unkown,qq_mail VARCHAR(20)
);对于整数类型的主键常配搭自增长 auto_increment 来使用。插入数据对应字段不给值时使用最大值 1。
-- 主键是 NOT NULL 和 UNIQUE 的结合可以不用 NOT NULL
id INT PRIMARY KEY auto_increment,6. FOREIGN KEY外键约束
外键用于关联其他表的主键或唯一键语法
foreign key (字段名) references 主表(列)示例
创建班级表 classesid 为主键
-- 创建班级表有使用MySQL关键字作为字段时需要使用来标识
DROP TABLE IF EXISTS classes;
CREATE TABLE classes (id INT PRIMARY KEY auto_increment,name VARCHAR(20),desc VARCHAR(100)
);创建学生表 student一个学生对应一个班级一个班级对应多个学生。使用 id 为主键classes_id 为外键关联班级表 id
-- 重新设置学生表结构
DROP TABLE IF EXISTS student;
CREATE TABLE student (id INT PRIMARY KEY auto_increment,sn INT UNIQUE,name VARCHAR(20) DEFAULT unkown,qq_mail VARCHAR(20),classes_id int,FOREIGN KEY (classes_id) REFERENCES classes(id)
);注意
外键字段不能为该表的主键外键必须参考主表的主键子表中对应的数据在父表中必须对应存在 新增 修改时都要遵循外键同样约束着父表当父表中某条记录被子表依赖时此时尝试进行修改或者删除都会失败
7. CHECK约束
drop table if exists test_user;
create table test_user (id int,name varchar(20),sex varchar(1),check (sex 男 or sex女)
);二. 表的设计
实体之间的关系
1. 一对一 2. 一对多 3. 多对多 创建课程表
-- 创建课程表
DROP TABLE IF EXISTS course;
CREATE TABLE course (id INT PRIMARY KEY auto_increment,name VARCHAR(20)
);创建学生课程中间表考试成绩表
-- 创建课程学生中间表考试成绩表
DROP TABLE IF EXISTS score;
CREATE TABLE score (id INT PRIMARY KEY auto_increment,score DECIMAL(3, 1),student_id int,course_id int,FOREIGN KEY (student_id) REFERENCES student(id),FOREIGN KEY (course_id) REFERENCES course(id)
);三. 新增
插入查询结果
语法
INSERT INTO table_name [(column [, column ...])] SELECT ...示例 创建一张用户表设计有name姓名、email邮箱、sex性别、mobile手机号字段。需要把已有的学生数据复制进来可以复制的字段为name、qq_mail
-- 创建用户表
DROP TABLE IF EXISTS test_user;
CREATE TABLE test_user (id INT primary key auto_increment,name VARCHAR(20) comment 姓名,age INT comment 年龄,email VARCHAR(20) comment 邮箱,sex varchar(1) comment 性别,mobile varchar(20) comment 手机号
);-- 将学生表中的所有数据复制到用户表
insert into test_user(name, email) select name, qq_mail from student;
注意
这里面没有使用 values。将查询结果插入另一个表中时 对应的列数和类型要匹配
四. 查询
1. 聚合查询
1. 聚合函数
常见的统计总数、计算平局值等操作可以使用聚合函数来实现常见的聚合函数有 (聚合函数里面也可以是表达式)
示例
COUNT
-- 统计班级共有多少同学
SELECT COUNT(*) FROM student;
SELECT COUNT(0) FROM student;-- 统计班级收集的 qq_mail 有多少个qq_mail 为 NULL 的数据不会计入结果
SELECT COUNT(qq_mail) FROM student;SUM
-- 统计数学成绩总分
SELECT SUM(math) FROM exam_result;-- 不及格 60 的总分没有结果返回 NULL
SELECT SUM(math) FROM exam_result WHERE math 60;AVG
-- 统计平均总分
SELECT AVG(chinese math english) 平均总分 FROM exam_result;
-- NULL 值不会被计入 不会影响平均值的结果MAX
-- 返回英语最高分
SELECT MAX(english) FROM exam_result;MIN
-- 返回 70 分以上的数学最低分
SELECT MIN(math) FROM exam_result WHERE math 70;2. GROUP BY子句
SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。 注意 使用 GROUP BY 进行分组查询时SELECT 指定的字段必须是“分组依据字段”其他字段若想出现在SELECT 中则必须包含在合函数中。虽然不报错 但是其他字段是没有意义的
select column1, sum(column2), .. from table group by column1,column3;示例 准备测试表及数据职员表有id主键、name姓名、role角色、salary薪水
create table emp(id int primary key auto_increment,name varchar(20) not null,role varchar(20) not null,salary numeric(11,2)
);
insert into emp(name, role, salary) values(马云,服务员, 1000.20),(马化腾,游戏陪玩, 2000.99),(孙悟空,游戏角色, 999.11),(猪无能,游戏角色, 333.5),(沙和尚,游戏角色, 700.33),(隔壁老王,董事长, 12000.66);查询每个角色的最高工资、最低工资和平均工资
select role,max(salary),min(salary),avg(salary) from emp group by role;3. HAVING
GROUP BY 子句进行分组以后需要对分组结果再进行条件过滤时不能使用 WHERE 语句而需要用HAVING where 是先筛选出结果 然后用 group 分组 再用 having 筛选出符合条件的分组
示例 显示平均工资低于1500的角色和它的平均工资
select role,max(salary),min(salary),avg(salary) from emp group by role having avg(salary)1500;2. 联合查询
实际开发中往往数据来自不同的表所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积 注意关联查询可以对关联表使用别名。
初始化测试数据
insert into classes(name, desc) values
(计算机系2019级1班, 学习了计算机原理、C和Java语言、数据结构和算法),
(中文系2019级3班,学习了中国传统文学),
(自动化2019级5班,学习了机械自动化);insert into student(sn, name, qq_mail, classes_id) values
(09982,黑旋风李逵,xuanfengqq.com,1),
(00835,菩提老祖,null,1),
(00391,白素贞,null,1),
(00031,许仙,xuxianqq.com,1),
(00054,不想毕业,null,1),
(51234,好好说话,sayqq.com,2),
(83223,tellme,null,2),
(09527,老外学中文,foreignerqq.com,2);insert into course(name) values
(Java),(中国传统文化),(计算机原理),(语文),(高阶数学),(英文);insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),
-- 白素贞
(33, 3, 1),(68, 3, 3),(99, 3, 5),
-- 许仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-- 不想毕业
(81, 5, 1),(37, 5, 5),
-- 好好说话
(56, 6, 2),(43, 6, 4),(79, 6, 6),
-- tellme
(80, 7, 2),(92, 7, 6);1. 内连接
语法
select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;示例 1查询“许仙”同学的 成绩
select sco.score from student stu inner join score sco on stu.idsco.student_id and stu.name许仙;
-- 或者
select sco.score from student stu, score sco where stu.idsco.student_id and stu.name许仙;2查询所有同学的总成绩及同学的个人信息
-- 成绩表对学生表是多对1关系查询总成绩是根据成绩表的同学id来进行分组的
SELECT stu.sn, stu.NAME, stu.qq_mail, sum( sco.score )
FROMstudent stu JOIN score sco ON stu.id sco.student_id
GROUP BYsco.student_id;3查询所有同学的成绩课程名字及同学的个人信息
-- 查询出来的都是有成绩的同学“老外学中文”同学 没有显示
select * from student stu join score sco on stu.idsco.student_id;
-- 学生表、成绩表、课程表3张表关联查询
SELECT stu.id, stu.sn, stu.NAME, stu.qq_mail, sco.score,sco.course_id, cou.NAME
FROMstudent stuJOIN score sco ON stu.id sco.student_idJOIN course cou ON sco.course_id cou.id
ORDER BYstu.id;2. 外连接
外连接分为左外连接和右外连接。如果联合查询左侧的表完全显示我们就说是左外连接右侧的表完全显示我们就说是右外连接。
语法
-- 左外连接表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件;-- 右外连接表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;示例 查询所有同学的成绩及同学的个人信息如果该同学没有成绩也需要显示
-- “老外学中文”同学 没有考试成绩也显示出来了
select * from student stu left join score sco on stu.idsco.student_id;-- 对应的右外连接为
select * from score sco right join student stu on stu.idsco.student_id;-- 学生表、成绩表、课程表3张表关联查询
SELECTstu.id,stu.sn,stu.NAME,stu.qq_mail,sco.score,sco.course_id,cou.NAME
FROMstudent stuLEFT JOIN score sco ON stu.id sco.student_idLEFT JOIN course cou ON sco.course_id cou.id
ORDER BYstu.id;3. 自连接
自连接是指在同一张表连接自身进行查询。
示例 显示所有 “计算机原理” 成绩比 “Java” 成绩高的成绩信息
-- 先查询“计算机原理”和“Java”课程的id
select id,name from course where nameJava or name计算机原理;-- 再查询成绩表中“计算机原理”成绩比“Java”成绩 好的信息
SELECTs1.*
FROMscore s1, score s2
WHEREs1.student_id s2.student_idAND s1.score s2.scoreAND s1.course_id 1AND s2.course_id 3;-- 也可以使用join on 语句来进行自连接查询
SELECTs1.*
FROMscore s1JOIN score s2 ON s1.student_id s2.student_idAND s1.score s2.scoreAND s1.course_id 1AND s2.course_id 3;以上查询只显示了成绩信息并且是分布执行的。要显示学生及成绩信息并在一条语句显示
SELECTstu.*,s1.score Java,s2.score 计算机原理
FROMscore s1JOIN score s2 ON s1.student_id s2.student_idJOIN student stu ON s1.student_id stu.idJOIN course c1 ON s1.course_id c1.idJOIN course c2 ON s2.course_id c2.idAND s1.score s2.scoreAND c1.NAME JavaAND c2.NAME 计算机原理;4. 自然连接
natural join 自然连接 要求两个多个表中字段名一样才能连接并且查询的结果会将重复的列删除 语法
select * from table1 natural join table2;5. 子查询
子查询是指嵌入在其他 sql 语句中的 select 语句也叫嵌套查询
单行子查询返回一行记录的子查询 查询与“不想毕业” 同学的同班同学
select * from student where classes_id(select classes_id from student where name不想毕业);多行子查询返回多行记录的子查询
示例 查询“语文”或“英文”课程的成绩信息
1[NOT] IN 关键字
-- 使用IN
select * from score where course_id in (select id from course where name语文 or name英文);
-- 使用 NOT IN
select * from score where course_id not in (select id from course where name ! 语文 and name!英文);可以使用多列包含
-- 插入重复的分数score, student_id, course_id列重复
insert into score(score, student_id, course_id) values
-- 黑旋风李逵
(70.5, 1, 1),(98.5, 1, 3),
-- 菩提老祖
(60, 2, 1);-- 查询重复的分数
SELECT*
FROMscore
WHERE( score, student_id, course_id ) IN ( SELECT score, student_id,
course_id FROM score GROUP BY score, student_id, course_id HAVING
count( * ) 1 );(2) [NOT] EXISTS 关键字
-- 使用 EXISTS
select * from score sco where exists (select sco.id from course cou
where (name语文 or name英文) and cou.id sco.course_id);-- 使用 NOT EXISTS
select * from score sco where not exists (select sco.id from course cou where (name!语文 and name!英文) and cou.id sco.course_id);在 from 子句中使用子查询子查询语句出现在 from 子句中。这里要用到数据查询的技巧把一个子查询当做一个临时表使用。 示例 查询所有比 “中文系2019级3班” 平均分高的成绩信息
-- 获取 “中文系2019级3班” 的平均分将其看作临时表
SELECTavg( sco.score ) score
FROMscore scoJOIN student stu ON sco.student_id stu.idJOIN classes cls ON stu.classes_id cls.idWHEREcls.NAME 中文系2019级3班;查询成绩表中比以上临时表平均分高的成绩
SELECT*
FROMscore sco,( SELECTavg( sco.score ) score FROMscore scoJOIN student stu ON sco.student_id stu.idJOIN classes cls ON stu.classes_id cls.idWHEREcls.NAME 中文系2019级3班) tmp
WHEREsco.score tmp.score;6. 合并查询
在实际应用中为了合并多个 select 的执行结果可以使用集合操作符 unionunion all。使用 UNION 和 UNION ALL 时前后查询的结果集中字段需要一致。
union 该操作符用于取得两个结果集的并集。当使用该操作符时会自动去掉结果集中的重复行。 示例 查询id小于3或者名字为“英文”的课程
select * from course where id3
union
select * from course where name英文;-- 或者使用or来实现
select * from course where id3 or name英文;union all 该操作符用于取得两个结果集的并集。当使用该操作符时不会去掉结果集中的重复行。
示例 查询id小于3或者名字为“Java”的课程
-- 可以看到结果集中出现重复数据Java
select * from course where id3
union all
select * from course where name英文;与 union 类似的两个表之间的操作还有 except 、intersect
except (差) 两表之差intersect (交) 两表的交集
五. 删除
删除 student 表中 age 最大的记录 delete from student where student.age (select * from (select max(age) from student)temp);将查询结果作为一个临时表temp 临时表中的值就是最大值但是我们需要 select * 才表示得到这个最大值不能直接让 student.age 直接等于这个表。
好啦 以上就是对 MySQL 表的进阶版增删改查的讲解 希望能帮到你 评论区欢迎指正