当前位置: 首页 > article >正文

初写MySQL四张表:(3/4)

我们已经完成了四张表的创建,学会了创建表和查看表字段信息的语句。

初写MySQL四张表:(1/4)-CSDN博客

初写MySQL四张表:(2/4)-CSDN博客

接下来,我们来学点对数据的操作:增 删 查(一部分)改

先来看这四张表以及相关需求:

四张表

 需求一:

这便是向我们创建好的空表里面,插入数据。具体语句我们使用INSERT INTO ,接下来介绍一番:

INSERT INTO:

先来申请英译中:

 现在是逻辑课:按照语法来说“插入到”后面得加个地点吧,题上不是说了嘛,“添加到学生表”。根据前面的习惯,表名我们会select一个DATABASE。

(我们可以看到左侧,学生表stu是放在testdb中的)

所以按照猜测语句应该有这样一部分:

INSERT INTO testdb.stu

后面按理说就应该是添数据对吧:但是一行数据我们要添加的数据项可能并不是全部字段(属性)——比如在stu表中,我们若添加数据只包含学号 、姓名 、学院编号。但是我们并不添加性别和出生日期这两个字段。

这种添加数据但是不包含所有字段的数据,需要我们自己指明要添加的字段名:

#假如,指定添加该学生的学号,姓名和学院编号
INSERT INTO testdb.stu(stuid,stuname,deptid)
...
#字段之间用逗号隔开

 如果你要添加的数据,包含全部的字段,这时候就不需要指明添加的字段名,默认你要添加所有字段。比如这里的需求:

 但是,我们添加的核心,始终是数据。

我们会添加一个关键字VALUES:而数据就放在VALUES();的括号中。这里就应该这样表示:

INSERT INTO testdb.stu
VALUES('2022121001','张三','男','2006-5-1','1');
#这是一行记录,一行记录的数据值之间也需要使用逗号隔开。其中字符型数据需要使用单引号。

 发现没有,所有数据值的顺序对应我们字段的顺序。

补充:

我们前面在创建表的时候,不是有个字段NOT NULL约束吗?NOT NULL到底什么时候约束呢?就是添加记录的时候。

INTO子句中没有出现的字段,新添加的记录在这些字段上将被赋NULL值。但是表定义时有NOT NULL约束的字段不能取NULL值,添加记录时必须给其赋值。

我们运行一下:

#Error Code: 1452. 
/*Cannot add or update a child row: 
a foreign key constraint fails (`testdb`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`deptid`) REFERENCES `dept` (`deptid`))*/

报错了,很好。具体错误是:无法添加或更新一个子行(row,在MySQL里,行也称作一条记录)。

外键约束无效:

原因是什么呢?是因为我们的外键约束失败了。外键为什么不行,还记得外键怎么来的吗?外键是另一张表的主键的引用,保证数据的完整性。不仅如此,从表中的外键列只能包含主表中已存在的主键值,避免了出现悬挂指针(指向不存在的数据)或数据不一致的情况。

外键能约束说明它心中已经有杆秤了,外键本质上是另一张表的主键。而有杆秤,说明该主表的主键列已经有值了——怎么至少也得有>=1个值吧,外键就依据这些现有的值来判断你添加的值是否有效了。——这就是外键约束。

解决方案:先在dept表里添加主键值,那就要我们再写一个INSERT INTO 呗,但是,你觉得这种写法可行吗?

INSERT INTO testdb.dept(deptid)
VALUES('1');

 看见没,前面的补充你只要明白了,这里你就知道为什么我们不能单单添加deptid了。NOT NULL约束对不对?

INSERT INTO testdb.dept
VALUES('1','计算机学院');

运行一下,添加记录。

此时再添加这条学生信息,想必就不会外键失效了。

INSERT INTO testdb.stu
VALUES('2022121001','张三','男','2006-5-1','1');

 

也成功了,但是文字的显示始终没有图形来得震撼。 

 我们前面说,DESC + 表名是查看表的字段信息,但是我们添加了数据,该怎么去看有数据的表呢?

SELECT * FROM

SELECT * FROM 表名;
#表名包括了数据库

 SELECT 表示筛选,*是通配符,表示"所有",FROM 表,连起来就是从某个表里的所有字段列中筛选数据——作用是:查询该表中的全部内容。

SELECT * FROM testdb.dept;
#刚刚添加了一条数据,我们来显示一下

是吧,添加成功了。

这里浅浅说说,方便我们检验操作,因为我们后面不远处,还会说到select 。

需求一的参考代码:

INSERT INTO testdb.dept
VALUES('1','计算机学院');
INSERT INTO testdb.stu
VALUES('2022121001','张三','男','2006-5-1','1');

需求二:

在学生表中删除学号为’2022121001’的学生信息。

分析需求:核心是删除一条记录,删的记录是哪里的? stu这张表里的。它直接报出了学号,咱们就得按照学号来检索删除。

按理说,这个“检索删除”有两步,但是学习的魅力就在于此:我们若只着眼于解决当下问题,就可以直接站在巨人的肩膀上,一步到位;但是我们若要追根溯源,探寻如何实现,也有前人给我们源码研究。

现在就允许我们先跪在巨人的肩膀上吧,学个DELETE from 

DELETE FROM

DELETE FROM 按照之前的设计后面也接个表名,你是这么猜,它也真的这么设计。这里就是:

DELETE FROM testdb.stu
#我没打分号就表示这不是一句完整的语句,提醒一句

WHERE

WHERE关键字,WHERE 是 SQL 语言中的一个关键字,它用于指定 DELETEUPDATESELECT 等语句中的条件,以限制哪些行(记录)会被影响或返回。

 此处,DELETE FROM ... WHERE ...其结果是:指定删除。

怎么用呢? 比如:学生表中,你要指定删除一个叫“王五”的学生。用DELETE FROM ...WHERE就是:

DELETE FROM testdb.stu WHERE stuname = '王五';
#指定删除学生表中学生姓名叫王五的学生的信息记录

运行当然运行不了,因为我们根本没添加过这条数据,我这里只是打个比方。

那实现这里的需求,也就照猫画虎了:

 在学生表中删除学号为’2022121001’的学生信息。

DELETE FROM testdb.stu WHERE stuid = '2022121001';

 运行之前,先看一下表里的数据:

再运行一下我们的删除语句:

显示删除成功了。(有时发现不知不觉就熬了夜☕哈哈哈) 

ok,我们通过select * 检查一下,是否真的删除了。

记录没了,确实删除了,直观吧

需求二的参考代码:

DELETE FROM testdb.stu WHERE stuid = '2022121001';

需求三:

把课程表中课程编号为“CS003A”的课程的学分改为3。 

分析:本质是什么,修改某条记录某个字段的值。关键词:修改表中的数据。

UPDATE ... SET ...

UPDATE 后面接表名,表示你要修改哪张表。SET 英译过来:“设置”,这里和修改同义。

SET 设置的是前面确定表名的某个或多个字段 的值。

扩展:还记得前面说过的,WHERE加在不同的地方有指定的xx功能。和delete搭在一起,有指定删除的功能,那和set搭在一起,就有指定修改的功能。哟,这不巧了嘛。

我们的需求就是:指定修改课程表里课程编号为'CS003A'的课程记录的学分字段的值。(话有点长,但意思我写得清楚🤞)

比如:我们要把学生表里面的姓名叫"张三"的学生记录中的出生日期改成"2006-5-2"。

UPDATE testdb.stu
SET birthday = '2006-5-2'
WHERE stuname = '张三';
#照样是举个例子

 那么,这个需求,实现也近在眼前了:

把课程表中课程编号为“CS003A”的课程的学分改为3。 

UPDATE testdb.course
SET credit = 3
WHERE cid = 'CS003A';
#字符型数据才会加单引号,这里的学分不是字符型数据

但是,我们自己会发现这个修改数据是建立在有数据的基础上,若没有CSA003A这条课程的记录,甚至谈不上指定数据 。所以,我们还得手动添加一条数据记录。

INSERT INTO testdb.course
VALUES('CS003A','数据库',2,'1');
#添加该课程编号整一条记录

那么我们先运行添加,查看:

再来修改学分为3:

好了,完成了需求三——修改数据。

需求三的参考代码:

UPDATE testdb.course
SET credit = 3
WHERE cid = 'CS003A';

需求四:

查询学号为“2022121001”的学生所有信息。

分析:指定查询。

查询我们用关键字:SELECT,刚刚后面接*表示所有字段记录,若只有SELECT * FROM 表名,就表示查询该表中的全部内容。

现在我们要指定查询,就要在后面加个WHERE,起到我们期望的“指定”的效果。

WHERE 后面一般接字段名 = 某个值。

比如这里的:指定的是“学号为“2022121001”的学生

WHERE stuid = '2022121001'

我们要实现的是“查询...所有信息”,前面再加上SELECT * FROM 表名

SELECT * FROM testdb.stu
WHERE stuid = '2022121001';

我们运行一下,看看查询最后的效果是怎样。

所以得到需求四的实现代码:

SELECT * FROM testdb.stu
WHERE stuid = '2022121001';

 需求五:

查询学院名称为“计算机学院”的学生名单,显示学号、姓名、学院。

分析:也是指定查询,SELECT ... FROM...WHERE...是跑不了了。但是特殊的需求是,并非如上个需求显示所有字段的数据,而是只显示部分字段数据。别忘了,学生表中只有学院编号,要让我们显示的不是学院编号,而是学院表里面才有的学院名称。

这次查询,不是单纯的在一张表上查询,而是两张表。

首先改变的,只有 “*” 变成对应的字段名。

#学号、姓名—— 这些字段来自stu表,后面FROM已经说明了是从学生表找。但是学院名称是在dept表中,则需要指明表
SELECT stuid,stuname,dept.deptname
FROM testdb.stu,testdb.dept
WHERE 

我们的查询条件应该接在WHERE后,条件是deptname = '计算机学院',而这里值得注意的是,怎么样把两张表连起来。这两张表有主从关系,主从关系从何而来,学生表的外键是学院表主键的有效引用。

没错就是,主键外键 —— 学生表的外键是学院表主键的有效引用。则同时满足stu.deptid = dept.deptid

SELECT stuid,stuname,dept.deptname
FROM testdb.stu,testdb.dept
WHERE stu.deptid = dept.deptid AND deptname = '计算机学院';

AND

在SQL中用于表示关系的逻辑操作符和关键字,AND表示“前后两个表达式为真,记录就会被包含在查询结果中。”,意思即“并且”。—— 呼应我们这里的学院名称为计算机学院 同时满足 两张表学员编号对应的要求。

运行效果:

查询学院名称为“计算机学院”的学生名单,显示学号、姓名、学院。

是不是挨个展示了 学号、姓名和学院名称。

这里,我们再介绍一种写法: 

JOIN关键字

你需要通过两个表来进行联合查询(JOIN),join关键字后接上另一张表名。当将JOIN关键词放于FROM子句中,应有关键词ON与之对应,以表明连接的条件。

以前我们使用WHERE后面接查询条件和连接条件,现在我们使用ON。

查询学院名称为“计算机学院”的学生名单,显示学号、姓名、学院。

代码应该是这样:

SELECT stuid,stuname,dept.deptname
FROM testdb.stu
JOIN testdb.dept
ON stu.deptid = dept.deptid AND deptname = '计算机学院';
#JOIN 后接另一张表,ON和JOIN连用,ON后接连接条件和查询条件

是不是一样的效果?

需求五的参考代码:

#第一种:WHERE
SELECT stuid,stuname,dept.deptname
FROM testdb.stu,testdb.dept
WHERE stu.deptid = dept.deptid AND deptname = '计算机学院';
#第二种:JOIN ON
SELECT stuid,stuname,dept.deptname
FROM testdb.stu
JOIN testdb.dept
ON stu.deptid = dept.deptid AND deptname = '计算机学院';
#记得 SELECT ... FROM... 和 JOIN ... ON ...常见搭配

今天写得倒是很扎实,哈哈哈(意满离)


http://www.kler.cn/a/311325.html

相关文章:

  • 每日一练:二分查找-搜索插入位置
  • openSUSE 环境下通过 zypper 安装软件
  • ArcGIS Pro属性表乱码与字段名3个汉字解决方案大总结
  • MyBatisPlus 用法详解
  • BERT配置详解1:构建强大的自然语言处理模型
  • Vite初始化Vue3+Typescrpt项目
  • 八股文-JVM
  • 黑马程序员Java笔记整理(day01)
  • 用idea编写并运行第一个spark scala处理程序
  • RK3568平台(网络篇)MAC地址烧录
  • 工业仪器仪表指针数据集
  • 基于Python实现的一个电影知识库QA系统
  • 网络安全 DVWA通关指南 DVWA Stored Cross Site Scripting (存储型 XSS)
  • 卷积和转置卷积的输出尺寸计算
  • Qt_显示类控件
  • 二叉树的层序遍历-广度优先遍历
  • 专题四_位运算( >> , << , , | , ^ )_算法详细总结
  • 图新地球-将地图上大量的地标点批量输出坐标到csv文件【kml转excel】
  • 汇编(实现C语言程序的调用)
  • TestDeploy v3.0构思
  • Vue2接入高德地图API实现搜索定位和点击获取经纬度及地址功能
  • 【Python报错已解决】ModuleNotFoundError: No module named ‘sklearn‘
  • 离散化c++
  • Django创建模型
  • 力扣(leetcode)每日一题 1184 公交站间的距离
  • 机器人相关知识的本身和价值