MySQL - 连表查询 Join On 详解

news/2024/12/22 13:22:15/

1. 连表查询详解

 市面上有 7 种连表查询, 总共归为三大类 : 

  • 左查询 LEFT JOIN    -- 以左表为基准
  • 右查询 RIGHT JOIN   --  以右表为基准
  • 交叉查询 INNER JOIN  -- 查询两表都有的数据
操作描述
inner  join如果表中至少有一个匹配, 就返回行
left  join会从左表中返回所有的值, 即使右表中没有匹配
right  join会从右表中返回所有的值, 即使左表中没有匹配

【测试数据】

1. 创建并使用 school 数据库.

CREATE DATABASE if NOT EXISTS `school`;USE DATABASE;

2. 创建 grade 表 (年级表 ) 并构造数据.

DROP TABLE IF EXISTS `grade`;CREATE TABLE `grade`(`GradeID` INT(11) NOT NULL AUTO_INCREMENT COMMENT '年级编号', `GradeName` VARCHAR(50) NOT NULL COMMENT '年纪名称',PRIMARY KEY (`GradeID`)
) ENGINE = INNODB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;INSERT INTO grade(GradeID,GradeName) VALUES(1,'大一');
INSERT INTO grade(GradeID,GradeName) VALUES(2,'大二');
INSERT INTO grade(GradeID,GradeName) VALUES(3,'大三');
INSERT INTO grade(GradeID,GradeName) VALUES(4,'大四');
INSERT INTO grade(GradeID,GradeName) VALUES(5,'预科班');

3.  创建 result 表 (成绩表) 并构造数据.

DROP TABLE IF EXISTS `result`;CREATE TABLE `result`(`StudentNo` INT(4) NOT NULL COMMENT '学号',`SubjectNo` INT(4) NOT NULL COMMENT '课程编号',`ExamDate` DATETIME NOT NULL COMMENT '考试时间',`StudentResult` INT(4) NOT NULL COMMENT '考试成绩',KEY `SubjectNo` (`subjectNo`)
)ENGINE=INNODB DEFAULT CHARSET = utf8;INSERT INTO `result`(`studentno`,`subjectno`,`examdate`,`studentresult`)
VALUES
(1000,1,'2023-06-25 09:00:00',85),
(1000,2,'2013-06-26 09:00:00',70),
(1000,3,'2013-06-27 09:00:00',68),
(1000,4,'2013-06-28 16:00:00',98),
(1000,5,'2013-06-29 16:00:00',68),
(1001,6,'2013-06-30 16:00:00',78),
(1002,7,'2013-07-01 16:00:00',88);

4. 创建 student 表 (学生表) 并构造数据.

DROP TABLE IF EXISTS `student`;CREATE TABLE student(`StudentNo` INT(4) NOT NULL COMMENT '学号' ,`Loginpwd` VARCHAR(20) DEFAULT NULL COMMENT '密码',`StudentName` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',`Sex` TINYINT DEFAULT NULL COMMENT '性别,0/1',`Gradeid` INT(11) DEFAULT NULL COMMENT '年纪编号',`Phone` VARCHAR(50) NOT NULL COMMENT '联系电话,不允许为空', `Address` VARCHAR(255) NOT NULL COMMENT '地址,不允许为空', `BornDate` DATETIME DEFAULT NULL COMMENT '出生时间', `Email` VARCHAR(50) NOT NULL COMMENT '邮箱账号,不允许为空',`IdentityCard` VARCHAR(18) DEFAULT NULL COMMENT '身份证号', PRIMARY KEY (`StudentNO`),  -- 主键UNIQUE KEY `IdentityCard` (`IdentityCard`), -- 唯一索引KEY `Email` (`Email`)        -- index索引
) ENGINE=INNODB DEFAULT CHARSET=utf8;INSERT INTO `student` (`studentno`,`loginpwd`,`studentname`,`sex`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`)
VALUES
(1000,'123456','张伟',0,2,'13800001234','北京朝阳','1980-1-1','text123@qq.com','123456434334011234'),
(1001,'123456','郭德',0,2,'13832343234','北京朝阳','1980-1-1','text123@qq.com','123456194001011234'),
(1002,'123456','李振',0,2,'13854325234','北京朝阳','1980-1-1','text123@qq.com','123456123001011234'),
(1003,'123456','刘强',0,2,'12130021234','北京朝阳','1980-1-1','text123@qq.com','123456193141011234'),
(1004,'123456','马云',0,2,'13832131234','北京朝阳','1980-1-1','text123@qq.com','123454332001011234'),
(1005,'123456','赵青',0,2,'13545441234','北京朝阳','1980-1-1','text123@qq.com','123456142101011234'),
(1006,'123456','赵强',1,3,'13805445222','广东深圳','1990-1-1','text111@qq.com','123132131301011233');

5. 创建 subject 表 (学科表)  并构造数据.

CREATE TABLE `subject`(`SubjectNo` INT(11) NOT NULL AUTO_INCREMENT COMMENT '课程编号',`SubjectName` VARCHAR(50) DEFAULT NULL COMMENT '课程名称',`ClassHour` INT(4) DEFAULT NULL COMMENT '学时',`GradeID` INT(4) DEFAULT NULL COMMENT '年纪编号',PRIMARY KEY(`SubjectNo`)
) ENGINE = INNODB DEFAULT CHARSET=utf8;INSERT INTO `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)VALUES
(1,'高等数学-1',110,1),
(2,'高等数学-2',110,2),
(3,'高等数学-3',100,3),
(4,'高等数学-4',130,4),
(5,'C语言-1',110,1),
(6,'C语言-2',110,2),
(7,'C语言-3',100,3),
(8,'C语言-4',130,4),
(9,'Java程序设计-1',110,1),
(10,'Java程序设计-2',110,2),
(11,'Java程序设计-3',100,3),
(12,'Java程序设计-4',130,4),
(13,'数据库结构-1',110,1),
(14,'数据库结构-2',110,2),
(15,'数据库结构-3',100,3),
(16,'数据库结构-4',130,4),
(17,'C#基础',130,1);

 

2. 连表查询示例

1. 查询参加了考试的同学 (查询列 : 学号, 姓名, 科目编号, 分数) -- 两表

【思路】

1. 分析查询的字段来自哪些表.

2. 确定使用哪种连接查询. 

3. 确定交叉点 (这两个表中哪些数据是相同的).

4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo.

5. 根据需求增加 where 等值查询. (可有可无)

  • 上述字段分别来自 student 表 (学号,姓名) 和 result 表 (科目编号,分数)
  • 因为需要查询参加考试的同学, 而学生表中有些学生是没有参加考试的, 所以以成绩表为基准, 所以使用右连接查询.

【SQL 实现】

-- RIGHT JOIN
SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM `student` s
RIGHT JOIN `result` r
ON s.StudentNo = r.StudentNo;

 

 如果使用左查询, 将会把没有参加考试的同学的行也查询出来, 就不符合题目要求 (查询参加考试的同学).

 

2.  查询缺考的同学 (学号, 姓名, 科目编号, 分数) -- 两表

【思路】

1. 分析查询的字段来自哪些表.

2. 确定使用哪种连接查询. 

3. 确定交叉点 (这两个表中哪些数据是相同的).

4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo.

5. 根据需求增加 where 等值查询 (可有可无).

  • 上述字段分别来自 student 表 (学号,姓名) 和 result 表 (科目编号, 分数)
  • 因为题目需要查询未参加考试的同学, 而成绩表中只有参加了考试的同学, 所以以左表为基准, 所以使用左连接查询.

【SQL 实现】

-- LEFT JOIN
SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM `student` s
LEFT JOIN `result` r
ON s.StudentNo = r.StudentNo
WHERE StudentResult IS NULL;

 

3. 查询参加考试的同学信息(学号, 学生姓名, 科目名称, 分数)-- 三表

【思路】

1. 分析查询的字段来自哪些表.

2. 确定使用哪种连接查询. 

3. 确定交叉点 (这两个表中哪些数据是相同的).

4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo.  成绩表中的 SubjectNo = 学科表中的 SubjectNo.

5. 根据需求增加 where 等值查询 (可有可无).

  • 上述字段分别来自 student 表 (学号,姓名) ,result 表 (分数) 和 subject 表 (科目名称)
  • 先查 student , rersult 两张表, 再连 subject 第三张表.
  • 对于 student 和 result 表, 要查询参加考试的同学, 使用右连接, 而对于这两张表查询出来的结果和 subject 进行连表查询时, 没有以哪张表为基准, 所以使用 inner join 就可以了.

【SQL 实现】

1. 先查 student 表 和 result 表

SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
FROM student s
RIGHT JOIN result r
ON s.StudentNo = r.StudentNo;

2. 再拿着查询结果与 subject 表进行连表查询

完整 SQL :

SELECT s.StudentNo '学号',StudentName '姓名',SubjectName '科目名称',StudentResult '考试成绩'
FROM student s
RIGHT JOIN result r
ON s.StudentNo = r.StudentNo
INNER JOIN `subject` sub
ON sub.SubjectNo = r.SubjectNo;

 

【总结】

整体查询思路 : 

1. 我要查询哪些数据  -> SELECT ...

2. 需要从哪几张表中查数据  -> FROM 表  XXX Join 连接的表 on  交叉条件.

3. 假设存在多张表 (> 2) 的查询,  先连接两张表进行查询, 再慢慢增加其他表.


http://www.ppmy.cn/news/686516.html

相关文章

Eigen笔记1:矩阵和向量的定义和赋值

1. 头文件声明 #include<eigen3/Eigen/Core> #include<eigen3/Eigen/Dense> #include<iostream>using Eigen::MatrxXd; using Eigen::VectorXd;2. 向量 2.1 列向量定义 Eigen::Vector2d c1;//2*1列向量, 数据类型d是double Eigen::Vector3d c2;//3*1列向量…

电脑怎么设置固定静态ip地址

电脑如何设置固定ip地址&#xff0c;因为很多业务都需要固定的静态IP访问网络&#xff0c;而本身宽带拨号是动态形式的&#xff0c;所以每次上网的IP地址都不一样&#xff0c;那么怎么样才能设置固定的IP地址。 下面就给大家分享一个最新的方法&#xff0c;不但可以设置固定IP…

为服务器设置固定IP地址

1、获取超级管理员权限 命令&#xff1a;$ su - 输入root密码 2、判断哪个网卡有流量&#xff0c;或者确定需要设置哪个网卡的固定ip 命令&#xff1a;# ifconfig PS&#xff1a;可以查询哪些网卡有流量 3、进入目录/etc/sysconfig/network-scripts/ 命令&#xff1a;# cd…

设置固定IP地址

如何在Windows上设置固定IP地址 第一步&#xff1a;Win键E&#xff0c;然后右键网络点击属性! 第二步&#xff1a;点击查看活动网络里的连接 第三步&#xff1a;接下来会显示WLAN状态&#xff0c;点击详细信息记下来&#xff0c;返回点击属性&#xff0c;在&#xff08;此连…

Windows设置固定IP

Windows 方法 1.打开控制面板&#xff0c;选择网络 2.打开网络和共享中心&#xff0c;再打开更多设备 3.选择我们需要设置的网络&#xff0c;这里我没插网线&#xff0c;鼠标右键选择属性 4.这里我们选择IPV4 5.设置ip&#xff0c;下面的子网掩码会自己填写&#xff0c;…

Win10(Win7)设置固定IP地址

局域网中的电脑IP是由路由器分时段自动分配的&#xff0c;IP地址随时间会自动改变。 这是由于路由器默认开启了DHCP&#xff08;Dynamic Host Configuration Protocol&#xff0c;动态主机设置协议&#xff09;&#xff0c;它是一个局域网的网络协议。 主要有两个用途&#x…

配置固定IP地址

1)为本机配置固定的网络地址 2)IP地址&#xff1a;192.168.8.128 3)子网掩码&#xff1a;255.255.255.0 4)关闭NetworkManager服务&#xff0c;禁止开机自启 5)重启network服务&#xff0c;查看配置 默认的网卡配置文件路径&#xff1a;/etc/sysconfig/network-scripts/ 。 网卡…

PC设置固定IP

PC的IP会变化&#xff0c;如何设置成固定IP呢&#xff1f; 准备工作&#xff1a; 按winR——输入cmd——命令行输入ifconfig/all&#xff0c;可以查看到当前使用的IP和DNS服务器 假设查看到的IP是&#xff1a;192.168.0.100 &#xff08;你自己的IP可能是其它数值&#xf…