赞
踩
市面上有 7 种连表查询, 总共归为三大类 :
操作 | 描述 |
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);
【思路】
1. 分析查询的字段来自哪些表.
2. 确定使用哪种连接查询.
3. 确定交叉点 (这两个表中哪些数据是相同的).
4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo.
5. 根据需求增加 where 等值查询. (可有可无)
【SQL 实现】
- -- RIGHT JOIN
- SELECT s.StudentNo,StudentName,SubjectNo,StudentResult
- FROM `student` s
- RIGHT JOIN `result` r
- ON s.StudentNo = r.StudentNo;
如果使用左查询, 将会把没有参加考试的同学的行也查询出来, 就不符合题目要求 (查询参加考试的同学).
【思路】
1. 分析查询的字段来自哪些表.
2. 确定使用哪种连接查询.
3. 确定交叉点 (这两个表中哪些数据是相同的).
4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo.
5. 根据需求增加 where 等值查询 (可有可无).
【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;
【思路】
1. 分析查询的字段来自哪些表.
2. 确定使用哪种连接查询.
3. 确定交叉点 (这两个表中哪些数据是相同的).
4. 写判断条件 : 学生表中的 StudentNo = 成绩表中的 StudentNo. 成绩表中的 SubjectNo = 学科表中的 SubjectNo.
5. 根据需求增加 where 等值查询 (可有可无).
【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) 的查询, 先连接两张表进行查询, 再慢慢增加其他表.
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。