MySQL(五)
关系
- 创建成绩表scores,结构如下
- id
- 学生
- 科目
- 成绩
- 思考:学生列应该存什么信息呢?
- 答:学生列的数据不是在这里新建的,而应该从学生表引用过来,关系也是一条数据;根据范式要求应该存储学生的编号,而不是学生的姓名等其它信息
- 同理,科目表也是关系列,引用科目表中的数据

- 创建表的语句如下
create table scores(
id int primary key auto_increment,
stuid int,
subid int,
score decimal(5,2)
);外键
- 思考:怎么保证关系列数据的有效性呢?任何整数都可以吗?
- 答:必须是学生表中id列存在的数据,可以通过外键约束进行数据的有效性验证
- 为stuid添加外键约束
alter table scores add constraint stu_sco foreign key(stuid) references students(id);
- 此时插入或者修改数据时,如果stuid的值在students表中不存在则会报错
- 在创建表时可以直接创建约束
create table scores(
id int primary key auto_increment,
stuid int,
subid int,
score decimal(5,2),
foreign key(stuid) references students(id),
foreign key(subid) references subjects(id)
);
外键的级联操作
- 在删除students表的数据时,如果这个id值在scores中已经存在,则会抛异常
- 推荐使用逻辑删除,还可以解决这个问题
- 可以创建表时指定级联操作,也可以在创建表后再修改外键的级联操作
- 语法
alter table scores add constraint stu_sco foreign key(stuid) references students(id) on delete cascade;
级联操作的类型包括:
- restrict(限制):默认值,抛异常
- cascade(级联):如果主表的记录删掉,则从表中相关联的记录都将被删除
- set null:将外键设置为空
- no action:什么都不做
先看个问题
- 问:查询每个学生每个科目的分数
- 分析:学生姓名来源于students表,科目名称来源于subjects,分数来源于scores表,怎么将3个表放到一起查询,并将结果显示在同一个结果集中呢?
- 答:当查询结果来源于多张表时,需要使用连接查询
- 关键:找到表间的关系,当前的关系是
- students表的id---scores表的stuid
- subjects表的id---scores表的subid
- 则上面问题的答案是:
select students.sname,subjects.stitle,scores.score
from scores
inner join students on scores.stuid=students.id
inner join subjects on scores.subid=subjects.id;
结论:当需要对有关系的多张表进行查询时,需要使用连接join
连接查询
- 连接查询分类如下:
- 表A inner join 表B:表A与表B匹配的行会出现在结果中
- 表A left join 表B:表A与表B匹配的行会出现在结果中,外加表A中独有的数据,未对应的数据使用null填充
- 表A right join 表B:表A与表B匹配的行会出现在结果中,外加表B中独有的数据,未对应的数据使用null填充
- 在查询或条件中推荐使用“表名.列名”的语法
- 如果多个表中列名不重复可以省略“表名.”部分
- 如果表的名称太长,可以在表名后面使用' as 简写名'或' 简写名',为表起个临时的简写名称
练习
- 查询学生的姓名、平均分
select students.sname,avg(scores.score)
from scores
inner join students on scores.stuid=students.id
group by students.sname;
- 查询男生的姓名、总分
select students.sname,avg(scores.score)
from scores
inner join students on scores.stuid=students.id
where students.gender=1
group by students.sname;
- 查询科目的名称、平均分
select subjects.stitle,avg(scores.score)
from scores
inner join subjects on scores.subid=subjects.id
group by subjects.stitle;
- 查询未删除科目的名称、最高分、平均分
select subjects.stitle,avg(scores.score),max(scores.score)
from scores
inner join subjects on scores.subid=subjects.id
where subjects.isdelete=0
group by subjects.stitle;
MySQL(五)的更多相关文章
- MySQL(五) MySQL中的索引详讲
序言 之前写到MySQL对表的增删改查(查询最为重要)后,就感觉MySQL就差不多学完了,没有想继续学下去的心态了,原因可能是由于别人的影响,觉得对于MySQL来说,知道了一些复杂的查询,就够了,但是 ...
- mysql五补充部分:SQL逻辑查询语句执行顺序
一 SELECT语句关键字的定义顺序 SELECT DISTINCT <select_list> FROM <left_table> <join_type> JOI ...
- mysql五:pymysql模块
一.介绍 之前都是通过MySQ自带的命令行客户端工具Mysql来操作数据库,那如何在Python程序中操作数据库呢?这就需要用到pymysql模块了. 这个模块本质就是一个套接字客户端软件,使用前需要 ...
- mysql五补充:SQL逻辑查询语句执行顺序(待完善)
一.SELECT语句关键字的定义顺序(语法顺序) SELECT DISTINCT <select_list> FROM <left_table> <join_type&g ...
- mysql五-2:多表查询
一 介绍 本节主题 多表连接查询 复合条件连接查询 子查询 准备表 company.employeecompany.department #建表 create table department( id ...
- mysql五:数据操作
一 介绍 MySQL数据操作: DML ======================================================== 在MySQL管理软件中,可以通过SQL语句中的 ...
- mysql五-1:单表查询
一 介绍 本节内容: 查询语法 关键字的执行优先级 简单查询 单条件查询:WHERE 分组查询:GROUP BY HAVING 查询排序:ORDER BY 限制查询的记录数:LIMIT 使用聚合函数查 ...
- mysql五:索引原理与慢查询优化
一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...
- Mysql(五):索引原理与慢查询优化
一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...
- MySQL(五) —— 子查询
子查询(SubQuery)是指出现在其他SQL语句内的SELECT语句. 如: SELECT * FROM t1 WHERE col1 = (SELECT col2 FROM t2); 其中 SELE ...
随机推荐
- OpenCV-Python入门教程4-颜色空间转换
一.颜色空间转换 import cv2 import numpy as np img = cv2.imread('lena.jpg') # 转换成灰度图 img_gray = cv2.cvtColor ...
- Java生成生成密码类
import java.util.Date; import java.util.Random; public class PasswordUtil { public final static Stri ...
- 【第一部分】09Leetcode刷题
一.位1的个数 题目:191. Number of 1 Bits C++ Soution 1: class Solution { public: int hammingWeight(uint32_t ...
- KnockoutJs学习笔记(三)
之前的文章主要针对的是单一的observable(即便是observableArray也是一种observable),而文档Using computed observables则主要是针对ko.com ...
- Java中堆内存和栈内存的区别
Java把内存分成两种,一种叫做栈内存,一种叫做堆内存. 在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配.当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空 ...
- 开始写博客,学习Linq
除了为处理数据提供全新的方法之外,LINQ还代表了一种朝着声明式以及函数式编程发展的转变. 当人们问我为什么要学习LINQ时,我会告诉他们LINQ可以处理XML.关系型数据以及内存中的集合,更会提到L ...
- webpack项目打包配置
webpack.config.js 文件中,其中“plugins”最为重要 var path = require("path"); const webpack = require( ...
- 10本Java架构师必读书籍
1.大型网站系统与JAVA中间件实践 本书围绕大型网站和支撑大型网站架构的Java中间件的实践展开介绍. 从分布式系统的知识切入,让读者对分布式系统有基本的了解:然后介绍大型网站随着数据量.访问量增长 ...
- 1419: Red is good
题解: 很简单的期望dp 转移方程显然,max一个0就可以了 #include <bits/stdc++.h> using namespace std; #define rep(i,h,t ...
- C# 之 反射性能优化3
阅读目录 开始 用Delegate优化反射的缺点 用Delegate优化反射的优点 用CodeDOM优化反射的优点 如何用好CodeDOM? 用CodeDOM优化反射的缺点 能不能不使用委托? 根据反 ...