在一张表中查询:先选择要显示的列,去掉重复、限制行数,再用各种条件筛选行。
MySQL 8.0 和 MySQL Workbench,机房电脑已装好。所有语句在 Workbench 的 SQL 编辑区中执行。
Ctrl+Enter 执行光标所在的一句,Ctrl+Shift+Enter 执行全部。Mac 上把 Ctrl 换成 ⌘。
输入法切到英文。表名、字段名不加引号,字符串值才用单引号。
在 teaching 库中重建教材的学生表 s、课程表 c、教师表 t、选课表 sc、授课表 tc,并装入教材中的数据,查询结果与课件例题一致。四次实验共用这份数据。
-- 第 6 章实验数据:教材 teaching 库的五张表和教材中的数据 -- 四次实验共用这一份数据。整段执行一次即可,数据改乱了重新执行就能恢复。 CREATE DATABASE IF NOT EXISTS teaching DEFAULT CHARACTER SET utf8mb4; USE teaching; -- 删除旧的表。先暂时关闭外键检查,库里有别的表引用它们时也能删除 SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS sc, tc, avgsal, s, c, t; SET FOREIGN_KEY_CHECKS = 1; -- 课程表 CREATE TABLE c ( cno CHAR(4) NOT NULL, cn VARCHAR(30) NOT NULL, ct INT, PRIMARY KEY (cno) ); -- 学生表 CREATE TABLE s ( sno CHAR(4) NOT NULL, sn VARCHAR(20) NOT NULL, sex CHAR(2), age INT, maj VARCHAR(30), dept VARCHAR(30), PRIMARY KEY (sno) ); -- 教师表 CREATE TABLE t ( tno CHAR(4) NOT NULL, tn VARCHAR(20) NOT NULL, sex CHAR(2), age INT, prof VARCHAR(20), maj VARCHAR(30), dept VARCHAR(30), sal DECIMAL(8,2), PRIMARY KEY (tno) ); -- 选课表 CREATE TABLE sc ( sno CHAR(4) NOT NULL, cno CHAR(4) NOT NULL, score DECIMAL(5,2), PRIMARY KEY (sno, cno), FOREIGN KEY (sno) REFERENCES s (sno), FOREIGN KEY (cno) REFERENCES c (cno) ); -- 授课表 CREATE TABLE tc ( tno CHAR(4) NOT NULL, cno CHAR(4) NOT NULL, tcdate DATE, PRIMARY KEY (tno, cno), FOREIGN KEY (tno) REFERENCES t (tno), FOREIGN KEY (cno) REFERENCES c (cno) ); INSERT INTO c VALUES ('c1','Java程序设计',40), ('c2','程序设计基础',48), ('c3','线性代数',48), ('c4','数据结构',64), ('c5','数据库系统',56), ('c6','数据挖掘',32), ('c7','高等数学',60), ('c8','控制理论',32); INSERT INTO s VALUES ('s1','王彤','女',18,'计算机','信息学院'), ('s2','苏乐','男',20,'信息','信息学院'), ('s3','林欣怡','女',19,'信息','信息学院'), ('s4','陶然','男',19,'自动化','工学院'), ('s5','魏立','男',17,'数学','理学院'), ('s6','何欣荣','女',21,'计算机','信息学院'), ('s7','赵琳琳','女',19,'数学','理学院'), ('s8','李轩','男',18,'自动化','工学院'); INSERT INTO t VALUES ('t1','刘杨','男',38,'教授','计算机','信息学院',3800.00), ('t2','石丽','女',28,'讲师','计算机','信息学院',2800.00), ('t3','顾伟','男',35,'副教授','计算机','信息学院',3200.00), ('t4','赵礼','男',45,'教授','自动化','工学院',4267.90), ('t5','赵希希','女',33,'副教授','数学','理学院',3332.67), ('t6','张刚','男',30,'讲师','计算机','工学院',2600.00); INSERT INTO sc VALUES ('s1','c1',90.50), ('s1','c2',88.00), ('s2','c4',70.00), ('s2','c5',57.00), ('s2','c6',81.50), ('s2','c7',NULL), ('s3','c1',75.00), ('s3','c2',76.50), ('s3','c4',85.00), ('s4','c1',93.00), ('s4','c2',82.00), ('s4','c6',NULL), ('s4','c7',68.00), ('s5','c2',79.00), ('s5','c7',84.00), ('s7','c3',77.00), ('s7','c5',62.00), ('s7','c7',100.00), ('s8','c2',66.00), ('s8','c3',96.00); INSERT INTO tc VALUES ('t1','c1','2021-09-03'), ('t1','c2','2021-09-04'), ('t2','c5','2021-03-06'), ('t2','c6','2021-09-06'), ('t3','c2','2021-03-08'), ('t3','c4','2021-09-08'), ('t4','c3','2021-03-10'), ('t5','c7','2021-09-12'), ('t5','c8','2021-03-15');
-- 查询课程表的全部列 SELECT * FROM c; -- 只查三列,列的顺序按这里写的顺序 SELECT sno, sn, maj FROM s; -- 用 AS 给每一列起中文别名 SELECT cno AS 课程号, cn AS 课程名, ct AS 课时 FROM c;
| SELECT * | 星号表示全部字段 |
| FROM c | 从课程表 c 中查询 |
| SELECT sno, sn, maj | 只显示这三列,结果中列的顺序和这里一致 |
| cno AS 课程号 | 结果中这一列显示为“课程号”,表中的字段名不变 |
-- 不加 DISTINCT,专业会重复出现 SELECT maj FROM s; -- 加上 DISTINCT,每个专业只出现一次 SELECT DISTINCT maj FROM s; SELECT DISTINCT tno FROM tc; -- 只返回前 3 行 SELECT sn, sno, maj FROM s LIMIT 3;
| DISTINCT | 写在 SELECT 后面,结果中完全相同的行只保留一行 |
| LIMIT 3 | 只返回结果的前 3 行 |
SELECT * FROM sc WHERE score >= 90; -- 字符串常量要加单引号 SELECT tno, tn, maj FROM t WHERE prof = '教授'; -- 两个条件满足一个即可,用 OR SELECT * FROM s WHERE maj = '计算机' OR maj = '数学'; -- 两个条件都要满足,用 AND SELECT tno, tn, prof FROM t WHERE age >= 30 AND age <= 40;
| score >= 90 | 大于或等于 90,包括 90 分 |
| prof = '教授' | 字符串要用单引号括起来 |
| OR | 两个条件满足其中一个即可 |
| AND | 两个条件同时满足 |
SELECT cno, cn, ct FROM c WHERE ct BETWEEN 30 AND 40; SELECT cno, cn, ct FROM c WHERE ct NOT BETWEEN 30 AND 40; SELECT sno, cno, score FROM sc WHERE cno IN ('c4', 'c6'); SELECT sno, cno, score FROM sc WHERE cno NOT IN ('c4', 'c6');
| BETWEEN 30 AND 40 | 包括 30 和 40,等价于 ct >= 30 AND ct <= 40 |
| NOT BETWEEN 30 AND 40 | 范围以外,等价于 ct < 30 OR ct > 40 |
| IN ('c4', 'c6') | 等于其中任意一个,等价于 cno = 'c4' OR cno = 'c6' |
| NOT IN ('c4', 'c6') | 和列表中每一个都不相等 |
-- % 代表任意多个字符 SELECT cno, cn, ct FROM c WHERE cn LIKE '%程序%'; -- _ 代表一个字符 SELECT * FROM c WHERE cn LIKE '_据%'; -- 判断空值只能用 IS NULL SELECT sno, cno FROM sc WHERE score IS NULL; -- 用等号判断空值,查不出任何行 SELECT sno, cno FROM sc WHERE score = NULL;
| LIKE '%程序%' | 课程名任意位置含有“程序” |
| LIKE '_据%' | 第一个字任意,第二个字是“据”,后面任意 |
| IS NULL | 判断字段的值是否为空 |
| score = NULL | NULL 不能用等号比较,条件不成立,结果为空 |