当前位置:   article > 正文

【狂神】MySQL - 连表查询 Join On 详解_mysql join on

mysql join on

1. 连表查询详解

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

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

【测试数据】

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

  1. CREATE DATABASE if NOT EXISTS `school`;
  2. USE DATABASE;

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

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

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

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

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

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

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

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

2. 连表查询示例

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

【思路】

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

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

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

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

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

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

【SQL 实现】

  1. -- RIGHT JOIN
  2. SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
  3. FROM `student` s
  4. RIGHT JOIN `result` r
  5. ON s.StudentNo = r.StudentNo;

 

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

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

【思路】

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

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

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

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

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

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

【SQL 实现】

  1. -- LEFT JOIN
  2. SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
  3. FROM `student` s
  4. LEFT JOIN `result` r
  5. ON s.StudentNo = r.StudentNo
  6. 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 表

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

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

完整 SQL :

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

【总结】

整体查询思路 : 

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

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/189039
推荐阅读
相关标签
  

闽ICP备14008679号