JOIN


- CREATE DATABASE IF NOT EXISTS `school`;
- -- 创建一个school数据库
- USE `school`;-- 创建学生表
- DROP TABLE IF EXISTS `student`;
- CREATE TABLE `student`(
- `studentno` INT(4) NOT NULL COMMENT '学号',
- `loginpwd` VARCHAR(20) DEFAULT NULL,
- `studentname` VARCHAR(20) DEFAULT NULL COMMENT '学生姓名',
- `sex` TINYINT(1) 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`)
- )ENGINE=MYISAM DEFAULT CHARSET=utf8;
-
- -- 创建年级表
- 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;
-
- -- 创建科目表
- DROP TABLE IF EXISTS `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 AUTO_INCREMENT = 19 DEFAULT CHARSET = utf8;
-
- -- 创建成绩表
- 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;
student

result

- -- ======= 联表查询 join ==============
- -- 查询参加了考试的同学(学号,姓名,科目编号,分数)
- SELECT * FROM student
- SELECT * FROM result
思路:
1、分析需求,分析查询的字段来自哪些表,(连接查询)
2、确定使用哪种连接查询?--------------------------- 7种
确定交叉点(这两个表中哪个数据是相同的)
判断的条件:学生表中的 studentNo = 成绩表 studentNo
join(判断条件) on(连接的表) 连接查询
where 等值查询
as是可以省略的,使用ON和where都是一样的
- -- INNER JOIN
- SELECT s.studentno,studentname,subjectno,studentresult
- FROM student AS s
- INNER JOIN result AS r
- WHERE s.studentno = r.studentno
输出结果:

RIGHT JOIN(右连接)
- -- RIGHT JOIN
- SELECT s.studentno,studentname,subjectno,studentresult
- FROM student AS s
- RIGHT JOIN result AS r
- ON s.studentno = r.studentno
输出结果:

left JOIN(左链接)
- -- left JOIN
- SELECT s.studentno,studentname,subjectno,studentresult
- FROM student AS s
- LEFT JOIN result AS r
- ON s.studentno = r.studentno
输出结果:

- -- 查询缺考的同学
- SELECT s.studentno,studentname,subjectno,studentresult
- FROM student AS s
- LEFT JOIN result AS r
- ON s.studentno = r.studentno
- WHERE studentresult IS NULL
思考题(查询了参加考试的同学信息:学号,学生姓名,科目名,分数)
- 分析需求,分析查询的字段来自哪些表,student、result、subject(连接查询)
- 确定使用哪种连接查询? 7种
- 确定交叉点(这两个表中哪个数据是相同的)
- 判断的条件:学生表中的 studentNo = 成绩表 studentNo
- s.后面不能加`` 其他的都可以加``
- -- s.后面不能加`` 其他的都可以加``
-
- SELECT s.studentno,`studentname`,`subjectname`,`studentresult`
- FROM `student` AS s
- RIGHT JOIN `result` AS r
- ON r.studentno = s.studentno
- INNER JOIN `subject` AS sub
- ON r.subjectno = sub.subjectno
输出结果:

| 操作 | 描述 |
| Inner join | 如果表中至少有一个匹配,就返回行 |
| left join | 会从左表中返回所有的值,即使右表中没有匹配 |
| right join | 会从右表中返回所有的值,即使左表中没有匹配 |
自连接
自己的表和自己的表连接,核心:一张表拆为两张一样的表即可
例子:

父类
先看pid,去找相同的pid(pid = 1),然后去列出对应的categoryid
| categoryid | categoryName |
| 2 | 信息安全 |
| 3 | 软件开发 |
| 5 | 美术设计 |
子类
| pid | categoryid | categoryName |
| 3 | 4 | 数据库 |
| 2 | 8 | 办公信息 |
| 3 | 6 | web开发 |
| 5 | 7 | ps技术 |
操作:查询父类对应的子类关系
子类的pid去对应父类的categoryid
| 父类 | 子类 |
| 软件开发 | 数据库 |
| 信息安全 | 办公系统 |
| 软件开发 | web开发 |
| 美术设计 | ps技术 |
- -- ==================自连接=======
- CREATE TABLE `category`(
- `categoryid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主题id',
- `pid` INT(10) NOT NULL COMMENT '父id',
- `categoryname` VARCHAR(50) NOT NULL COMMENT '主题名字',
- PRIMARY KEY (`categoryid`)
- )ENGINE=INNODB AUTO_INCREMENT=9 DEFAULT CHARSET = utf8;
-
- INSERT INTO `category` (`categoryid`, `pid`, `categoryname`)
- VALUES ('2','1','信息技术'),
- ('3','1','软件开发'),
- ('5','1','美术设计'),
- ('4','3','数据库'),
- ('8','2','办公信息'),
- ('6','3','web开发'),
- ('7','5','ps技术');
-
- -- 查询父子信息:把一张表看成为两个一摸一样的表
- SELECT a.`categoryname` AS '父栏目',b.`categoryname` AS '子栏目'
- FROM `category` AS a,`category` AS b
- WHERE a.`categoryid` = b.`pid`
-
- -- 查询学员所属的年级(学号,学生的姓名,年级名称)
- SELECT studentno,studentname,`gradename`
- FROM student AS s
- INNER JOIN `grade` AS g
- ON s.`gradeid` = g.`gradeid`
-
- -- 查询科目所属的年级(科目名称,年级名称)
- SELECT `subjectname`,`gradename`
- FROM `subject` AS sub
- INNER JOIN `grade` AS g
- ON sub.`gradeid` = g.`gradeid`
-
- -- 查询了参加 数据库结构-1 考试的同学信息:学号,学生姓名,科目名,分数
- SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
- FROM `student` AS s
- INNER JOIN `result` AS r
- ON s.`studentno`=r.`studentno`
- INNER JOIN `subject` AS sub
- ON sub.`subjectno` = r.`subjectno`
- WHERE `subjectname` = '数据结构-1'
SELECT语法
- SELECT [ALL | DISTINCT]
- {* | table.* | [table.field1[AS aliasl][, table.field2[AS alias2]][,.....]]}
- FROM table_name [AS table_alias]
- [LEFT | RIGHT | ineer JOIN table_name2] -- 联合查询
- [WHERE ....] -- 指定结果需满足的条件
- [GROUP by.....] -- 指定结果按照哪几个字段来分组
- [HAVING] -- 过滤分组的记录必须满足的次要条件
- [ORDER by.....] -- 指定查询记录按一次或多个条件排序
- [LIMIT {[OFFSET,]ROW_COUNT | row_countoffset OFFSET}]
- -- 指定查询的记录从哪条到哪条
注意: