MySQL表的增删改查---多表查询和联合查询

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客

系列专栏:xiaoxie的MySql学习系列专栏——CSDN博客●'ᴗ'σσணღ
我的目标:"团团等我💪( ◡̀_◡́ ҂)" 

( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​+关注(互三必回)!

一. 数据库约束 

1.NOT NULL - 指示某列不能存储 NULL 值。

2.UNIQUE - 保证某列的每行必须有唯一的值。

3.DEFAULT - 规定没有给列赋值时的默认值。

4.PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列(或两个列多个列的结合)有唯一标 识,有助于更容易更快速地找到表中的一个特定的记录。

5.FOREIGN KEY - 保证一个表中的数据匹配另一个表中的值的参照完整性。

6.CHECK - 保证列中的值符合指定的条件。对于MySQL数据库,对CHECK子句进行分析,但是忽略 CHECK子句。

这些约束条件在数据库中起着非常重要的作用,可以确保数据的完整性和一致性。在设计数据库表结构时,合理地运用这些约束条件可以有效地避免数据错误和不一致性。

案例示范:

 create table student(
    -> id int primary key auto_increment,--主键约束,并且自动加1
    -> name varchar(20) not null,--不能为空
    -> qq int unique,--值唯一
    -> age int default 18,--赋值默认值
    -> gender varchar(2) check (gender = '男生' or gender = '女生'),--保证性别为男生或女生
    -> classid int,
    -> foreign key (classid) references class(id) -- 外键基于外键 classid和class表的主键 id在两个表之间建立联系
    -> );

结果:

使用 desc 表名 查看表结构

desc student

这时候我们插入表的数据就受到数据库的约束了例如我们可以插入一条不符合数据库的约束的数据查看一下

insert into student values(1,"张三",1234,null,"未知",2);

例如我们插入一条性别为未知的数据可以看到 

不符合CHECK条件的数据无法插入.博主在这里就验证这一条约束,别的就不过多的赘述了.

注意实现

  1. NOT NULL

    • NOT NULL 约束用于确保指定列不能存储NULL值。这意味着,在插入新记录或更新现有记录时,该列必须包含有效数据。
    • 注意:在设计表结构时应谨慎使用NOT NULL约束,特别是在考虑业务逻辑和未来扩展性时,要确保所有必要的数据都能在任何时候提供。
  2. UNIQUE

    • UNIQUE 约束强制某一列(或多个列组合)中的每行都具有唯一的值,不允许重复。
    • 注意:对于多列组成的唯一键,只要这些列的组合不重复即可,单个列可以有重复值。另外,每个表只能有一个主键约束,但可以有多个UNIQUE约束。
  3. DEFAULT

    • DEFAULT 约束为指定列定义一个默认值,当插入新记录时如果没有明确为该列赋值,则自动填充这个预设值。
    • 注意:默认值的选择应该符合业务逻辑,并且对于可能需要特殊处理的值(如时间戳、序列号等),需要考虑是否需要触发器或者程序逻辑来动态生成更复杂的默认值。
  4. PRIMARY KEY

    • PRIMARY KEY 是一种特殊的约束,它结合了NOT NULL 和 UNIQUE 的特点,即主键列的值不能为空,并且每一行的主键值在整个表中必须是唯一的。
    • 注意:每个表只能有一个主键,它可以是一个单列或多列的组合(复合主键)。主键通常被用作索引,有助于快速定位和查询特定记录。
  5. FOREIGN KEY:(特别关注)

    • FOREIGN KEY 约束用于维护两个表之间的引用完整性,确保一个表中的列(外键列)的值必须匹配另一个表(参照表)的主键列的值。
    • 注意:在设置外键约束时,要考虑删除规则(ON DELETE CASCADE, SET NULL, NO ACTION等)和更新规则(ON UPDATE CASCADE等),以避免违反引用完整性和级联操作带来的影响。
  6. CHECK

    • CHECK 约束理论上允许你限制列的值必须满足特定条件,例如年龄必须在0到120之间这样的范围检查。
    • 注意:在MySQL中,默认情况下并不支持标准SQL的CHECK约束进行行级的数据验证。尽管可以在创建表时编写CHECK子句,但MySQL会忽略执行这些约束,除非在某些特定存储引擎下或通过触发器模拟实现类似功能。在其他数据库系统如Oracle、PostgreSQL中,CHECK约束会被正常执行并用于保证列值符合特定条件。

总之,在实际应用中合理使用这些约束能够有效地维护数据库的一致性和完整性,但在MySQL中尤其要注意其对CHECK约束的支持情况,以确保数据验证机制的有效实施。

 二.表的设计

1.1对1

在一对一关系中,一个表中的每一行只与另一个表中的一行相关联,反之亦然。

例如:每个员工(Employee)可能有一个唯一的身份证记录(IDCard)。在这种情况下,可以有两种设计方式:

方式一(共享主键)

CREATE TABLE Employee (
    ID INT PRIMARY KEY AUTO_INCREMENT,
    Name VARCHAR(50),
    -- 其他字段...
);

CREATE TABLE IDCard (
    ID INT PRIMARY KEY, -- 使用相同的主键
    CardNumber VARCHAR(20),
    EmployeeDetails VARCHAR(100), -- 其他与身份证相关的字段
    FOREIGN KEY (ID) REFERENCES Employee(ID)
);

这种方式下,Employee表和IDCard表共享同一个主键,即Employee的ID也是IDCard的主键。

方式二(独立主键,但使用唯一外键约束)

CREATE TABLE Employee (
    EmployeeID INT PRIMARY KEY AUTO_INCREMENT,
    Name VARCHAR(50),
    -- 其他字段...
);

CREATE TABLE IDCard (
    ID INT PRIMARY KEY AUTO_INCREMENT,
    EmployeeID INT UNIQUE,
    CardNumber VARCHAR(20),
    EmployeeDetails VARCHAR(100),
    FOREIGN KEY (EmployeeID) REFERENCES Employee(EmployeeID)
);

在这种设计中,两个表各自有自己的主键,并且通过EmployeeID字段建立外键约束,确保IDCard表中每张身份证只对应一个Employee。

2.1对多

在一对多关系中,一个表的一行可以与另一个表的多行关联,但反过来不行。

例如:一个部门(Department)可以有多个员工(Employee),但每个员工只能属于一个部门。

CREATE TABLE Department (
    DeptID INT PRIMARY KEY AUTO_INCREMENT,
    DeptName VARCHAR(50)
);

CREATE TABLE Employee (
    EmployeeID INT PRIMARY KEY AUTO_INCREMENT,
    Name VARCHAR(50),
    DeptID INT,
    FOREIGN KEY (DeptID) REFERENCES Department(DeptID)
);

在这个例子中,Department表的每一个DeptID在Employee表中作为外键出现多次,表明了一个部门可以拥有多个员工。

3.多对多

在多对多关系中,一个表的每一行都可以与另一个表的多行关联,反之亦然。

例如:一个老师(Teacher)可以教多个学生(Student),而一个学生也可以被多个老师教授。

CREATE TABLE Teacher (
    TeacherID INT PRIMARY KEY AUTO_INCREMENT,
    Name VARCHAR(50)
);

CREATE TABLE Student (
    StudentID INT PRIMARY KEY AUTO_INCREMENT,
    Name VARCHAR(50)
);

CREATE TABLE TeacherStudent (
    TeacherID INT,
    StudentID INT,
    PRIMARY KEY (TeacherID, StudentID),
    FOREIGN KEY (TeacherID) REFERENCES Teacher(TeacherID),
    FOREIGN KEY (StudentID) REFERENCES Student(StudentID)
);

在这种情况下,需要创建一个中间表(TeacherStudent),它包含两个外键分别引用Teacher和Student表的主键,以此来存储这种多对多的关系信息。

 三.查询

1.聚合查询

函数说明
count(数据)返回查询到的数据的 数量
sum(数据)返回查询到的数据的 总和,不是数字没有意义
avg(数据)返回查询到的数据的 平均值,不是数字没有意义
max(数据)返回查询到的数据的 最大值,不是数字没有意义
min(数据)返回查询到的数据的 最小值,不是数字没有意义

语法:

select 聚合函数(数据) from + 表名 + where 条件

2.GROUP BY子句

SELECT 中使用 GROUP BY 子句可以对指定列进行分组查询。需要满足:使用 GROUP BY 进行分组查 询时,SELECT 指定的字段必须是“分组依据字段”,其他字段若想出现在SELECT 中则必须包含在聚合函 数中。 

语法:

select 列名1,列名2....from 表名 group by 列名1....

案例:

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 name,role,max(salary),min(salary),avg(salary) from emp group by role;

结果:

 3 HAVING

GROUP BY 子句进行分组以后,需要对分组结果再进行条件过滤时,不能使用 WHERE 语句,而需要用 HAVING

案例:

显示平均工资低于1500的角色和它的平均工资

select name,role,avg(salary) from emp group by role having avg(salary) < 1500;

 四.多表查询

实际开发中往往数据来自不同的表,所以需要多表联合查询。多表查询是对多张表的数据取笛卡尔积:

准备实验数据

创建班级表:

create table class(id int primary key auto_increment,name varchar(20));

创建学生表:

 create table student(
     id int primary key auto_increment,
     sn int unique,
     name varchar(20) default "unkown",
     qq_mail varchar(20),
     class_id int,
     foreign key(class_id) references class(id));

创建课程表:

create table course(id int primary key auto_increment,name varchar(20));

创建学生课程中间表,考试成绩表:

 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 class(name)values("计科"),("软工"),("网络");
 insert into student(sn, name, qq_mail, class_id) values
     ('09982','黑旋风李逵','xuanfeng@qq.com',1),
     ('00835','菩提老祖',null,1),
     ('00391','白素贞',null,1),
     ('00031','许仙','xuxian@qq.com',1),
     ('00054','不想毕业',null,1),
     ('51234','好好说话','say@qq.com',2),
     ('83223','tellme',null,2),
     ('09527','老外学中文','foreigner@qq.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);

4.1内连接

语法:

select 字段 from 表1 别名1 [inner] join 表2 别名2 on 连接条件 and 其他条件;
select 字段 from 表1 别名1,表2 别名2 where 连接条件 and 其他条件;

案例:1)查询“许仙”同学的 成绩 

select student.name,score.score from student,score where student.id = score.student_id and student.name = "许仙";
 select student.name,score.score from student join score on student.id = score.student_id and student.name = "许仙";

(2)查询所有同学的总成绩,及同学的个人信息:

select student.sn,student.name,student.qq_mail,sum(score) as total
    from student join score
    on student.id = score.student_id
    group by score.student_id;

 

总结来说:内连接我们一开始不熟练可以以下几步来做

1.先确定我们要查询的信息,来自那几张表

2.针对这几张表进行笛卡尔积

3.加上连接条件,去除无效数据

4.在根据题目要求,加上其他条件

5.继续根据题目要求看需要查询的是那些列,把不需要的去除即可,例如案例一,我们只需要知道许仙的名字和成绩, select student.name,score.score 这样即可

4.2外连接

语法:

-- 左外连接,表1完全显示
select 字段名  from 表名1 left join 表名2 on 连接条件;
-- 右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件;

案例:查询所有同学的成绩,及同学的个人信息,如果该同学没有成绩,也需要显示

select * from student left join score on student.id = score.student_id;

 

 4.3自连接

自连接是指在同一张表连接自身进行查询。也就是自己对自己进行笛卡尔积,属于是对待特殊问题的特殊技巧

案例:显示所有“计算机原理”成绩比“Java”成绩高的成绩信息

 SELECT
     s1.*
     FROM
      score s1
     JOIN score s2 ON s1.student_id = s2.student_id
     AND s1.score < s2.score
     AND s1.course_id = 1 --java的课程号
     AND s2.course_id = 3;--计算机原理的课程号

这个SQL查询从“score”表中选择所有记录,其中学生在Java课程(course_id = 1)中的分数高于计算机原理课程(course_id = 3)中的分数。该查询在“score”表上使用自连接来比较同一学生在两门课程中的分数。

自连接是指在同一个表中进行连接操作。在这种情况下,我们使用表的别名来区分不同的实例。以下是自连接的步骤:

  1. 为表分配别名:在查询中为同一张表分配不同的别名,以便区分它们。在这个例子中,我们使用了s1和s2作为score表的别名。

  2. 指定连接条件:在JOIN子句中指定连接条件,以便确定两个表之间的关联。在这个例子中,连接条件是s1.student_id = s2.student_id,表示两个实例具有相同的学生ID。

  3. 添加过滤条件:在ON子句中添加额外的条件来过滤出符合特定条件的记录。在这个例子中,过滤条件是s1.score < s2.score,s1.course_id = 1和s2.course_id = 3。

  4. 选择需要的列:在SELECT子句中指定要检索的列。在这个例子中,我们选择了s1.*,表示选择s1表中的所有列。

  5. 执行查询:执行SQL查询以获取符合条件的结果集。

4.4 子查询

子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询 

1.单行子查询:返回一行记录的子查询 查询与“不想毕业” 同学的同班同学:

 select * from student where class_id=(select class_id from student where
     name='不想毕业');

 多行子查询:返回多行记录的子查询 案例:查询“语文”或“英文”课程的成绩信息:

(not)in关键字

 -- 使用IN
 select * from score where course_id in (select id from course where
     name='语文' or name='英文');

 (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)

 

4.5 合并查询 

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符 union,union all。使用UNION 和UNION ALL时,前后查询的结果集中,字段需要一致。

1.union

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。 案例:查询id小于3,或者名字为“英文”的课程:

select * from course where id<3
union
select * from course where name='英文';
-- 或者使用or来实现
select * from course where id<3 or name='英文';

 2.union all

该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。 案例:查询id小于3,或者名字为“Java”的课程

-- 可以看到结果集中出现重复数据Java
select * from course where id<3
union all
select * from course where name='Java';

 

 以上就是博主关于MySQL的多表查询和联合查询的全部类型了,感谢您的阅读

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/483831.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

保研复习概率论1

1.什么是随机试验&#xff08;random trial&#xff09;&#xff1f; 如果一个试验满足试验可以在相同的条件下重复进行、试验所有可能结果明确可知&#xff08;或者是可知这个范围&#xff09;、每一次试验前会出现哪个结果事先并不确定&#xff0c;那么试验称为随机试验。 …

ssm+vue的消防物资存储系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的消防物资存储系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

PyQT5学习--新建窗体模板

目录 1 Dialog 2 Main Window 3 Widget Dialog 模板&#xff0c;基于 QDialog 类的窗体&#xff0c;具有一般对话框的特性&#xff0c;如可以模态显示、具有返回值等。 Main Window 模板&#xff0c;基于 QMainWindow 类的窗体&#xff0c;具有主窗口的特性&#xff0c;窗口…

重生奇迹mu弓箭手技能

1、弓箭手职业技能&#xff1a;多重箭&#xff1a;同时射出三发弓箭&#xff0c;给予复数敌人伤害&#xff0c;根据弓的不同&#xff0c;射出的数量也不同。天堂之箭&#xff1a;弓箭垂直射向天际&#xff0c;准确的落在敌人的头顶上&#xff0c;造成严重的伤害。 2、连技技能…

动态规划之数字三角形模型

题目&#xff1a;1015. 摘花生 思路 很经典的动态规划问题。 定义&#xff1a;v[i][j]表示位置是i,j的花生数量&#xff0c;f[i][j]表示走到位置i,j所能获得的最大花生数量。初始状态&#xff1a;f[1][1],目标状态&#xff1a;f[n][m]状态转移&#xff1a;由于题目规定只能向…

2024-03-24 需求分析-智能问答系统-调研

一. 需求列表 基于本地知识库的问答系统对接外围系统 数字人语音识别二. 待调研的公司 2.1 音视贝 AI智能外呼_大模型智能客服系统_大模型知识库系统_杭州音视贝 (yinshibei.com) 2.2 得助智能 智能AI客服机器人-智能电话机器人客服-电话电销机器人-得助智能 (51ima.com) 2…

Redis常见数据类型(1)

Redis提供了5种数据结构, 理解每种数据类型的特点对于Redis开发运维非常重要, 同时掌握每种数据类型的常见命令, 会在使用Redis的时候做到游刃有余. 内容如下: 预备知识: 几个全局命令, 数据结构和内部编码, 单线程机制解析. 5种数据类型的特点, 命令使用, 应用场景示例. 键遍历…

03-SparkSQL入门

0 Shark Spark 的一个组件&#xff0c;用于大规模数据分析的 SQL 查询引擎。Shark 提供了一种基于 SQL 的交互式查询方式&#xff0c;可以让用户轻松地对大规模数据集进行查询和分析。Shark 基于 Hive 项目&#xff0c;使用 Hive 的元数据存储和查询语法&#xff0c;并基于Hiv…

信号的小波包能量谱计算(以轴承振动信号为例,Python环境)

小波分析是近30年来发展起来的数学分支&#xff0c;是Fourier分析划时代发展的结果&#xff0c;由法国工程师Morlet首先提出&#xff0c;后广泛应用于信号处理、图像处理与分析、地震勘探、故障诊断、自动控制等领域&#xff0c;小波就是小的波形&#xff0c;所谓“小”是指它具…

备忘录导出的HTML文档转换MarkDown尝试记录

备忘录导出的HTML文档转换MarkDown尝试记录 1. pandoc命令行2. HTML转换MARKDOWN3. MD导入CSDN记录过长报错及压缩尝试参考 本地备忘录写了些旅游攻略&#xff0c;想做个纪念&#xff0c;导出为长图片ok&#xff0c;导出为HTML&#xff0c;也可以。但是导出图片是base64格式的&…

2、事件修饰符、双向绑定、style样式使用、v-for循环遍历、v-if 和 v-show

一、事件修饰符 1、.stop 阻止冒泡事件 给谁加了阻止冒泡事件&#xff0c;谁下面的盒子就不会执行了 <div id"app"><div class"parent" click"log3"><div class"child" click"log2"><button click.…

厨师上门服务小程序开发与运营指南

随着移动互联网的普及&#xff0c;各种生活服务类APP应运而生。厨师上门服务小程序作为一种新型的服务模式&#xff0c;为用户提供了便捷、个性化的餐饮服务。本文将为您介绍厨师上门服务小程序的开发与运营方法&#xff0c;帮助您快速搭建起一款实用的小程序。 一、小程序开发…

MyEclipse打开文件跳转到notepad打开问题

问题描述 windows系统打开README.md文件&#xff0c;每次都需要右键选择notepad打开&#xff0c;感觉很麻烦&#xff0c;然后就把README.md文件打开方式默认选择了notepad&#xff0c;这样每次双击就能打开&#xff0c;感觉很方便。 然后某天使用MyEclipse时&#xff0c;双击RE…

Linux系统——硬件命令

目录 一.网卡带宽 1.查看网卡速率——ethtool 网卡名 2.查看mac地址——ethtool -P 网卡名 二、内存相关 1.显示系统中内存使用情况——free -h 2.显示内存模块的详细信息——dmidecode -t memory 三、CPU相关 1.查看CPU架构信息——lscpu 2.性能模式 四、其他硬件命…

网络:DHCP 协议简介

文章目录 1. 前言2. DHCP 协议简介2.1 DHCP 客户端广播 DHCPDISCOVER 消息2.2 DHCP 服务器回复 DHCPOFFER 消息2.3 DHCP 客户端广播 DHCPREQUEST 消息2.4 DHCP 服务器回复 DHCPACK 消息2.5 剩余的工作 3. 参考资料 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&…

h5增强表单---数据列表和属性

h5增强表单---数据列表 下拉列表 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</ti…

Echarts功能记录

基础配置 工具箱toolbox 对应功能 案例中使用到的第三方脚本

力扣450 删除二叉搜索树中的节点 Java版本

文章目录 题目描述思路代码 题目描述 给定一个二叉搜索树的根节点 root 和一个值 key&#xff0c;删除二叉搜索树中的 key 对应的节点&#xff0c;并保证二叉搜索树的性质不变。返回二叉搜索树&#xff08;有可能被更新&#xff09;的根节点的引用。 一般来说&#xff0c;删除…

学生如何帮老师撰写审稿意见

开头先介绍这篇文章做了什么&#xff0c;达到了什么样的目的、有什么创新点、应用&#xff0c;然后第一段最后一句写上&#xff0c;如果你进行了如下补充&#xff0c;明确表达了相关内容等&#xff0c;就能够接收你的文章&#xff08;在我们暂时不想接收他的文章的情况下&#…

JetPack之ViewModel

目录 一、简介1.1 优点1.2 生命周期 二、使用2.1 ViewModel保证数据稳定性demo2.2 ViewModel中如何传递上下文Context 三、注意点 一、简介 ViewModel 组件用于管理界面相关的数据&#xff0c;并且在配置更改&#xff08;如屏幕旋转&#xff09;时保持数据的一致性。ViewModel…