MySQL学习笔记
P16 数据表设计-第一范式 1NF
数据库的三大设计范式.sql
第一范式(1NF):数据表中的所有字段都是 不 可 分 割 的 原 子 值 \color{red}{不可分割的原子值} 不可分割的原子值。
备注说明:数据库表中的字段都是单一属性的,不可再继续拆分。如地址就不是,地址可继续拆分。这个单一属性由基本类型构成,包括整型、实数、字符型、逻辑型、日期型等。
mysql> create table student2(
-> id int primary key,
-> name varchar(20),
-> address varchar(30)
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> insert into student2 values(1, '张三', '中国四川省成都市武侯区武侯大道100号');
Query OK, 1 row affected (0.01 sec)
mysql> insert into student2 values(2, '张三', '中国四川省成都市武侯区京城大道200号');
Query OK, 1 row affected (0.00 sec)
mysql> insert into student2 values(3, '张三', '中国四川省成都市高新区天府大道90号');
Query OK, 1 row affected (0.00 sec)
mysql> select * from student2;
+----+--------+-----------------------------------------------------+
| id | name | address |
+----+--------+-----------------------------------------------------+
| 1 | 张三 | 中国四川省成都市武侯区武侯大道100号 |
| 2 | 张三 | 中国四川省成都市武侯区京城大道200号 |
| 3 | 张三 | 中国四川省成都市高新区天府大道90号 |
+----+--------+-----------------------------------------------------+
3 rows in set (0.00 sec)
字段值还可以继续拆分的数据表,不满足 第一范式!
mysql> create table student3(
-> id int primary key,
-> name varchar(20),
-> country varchar(30),
-> province varchar(30),
-> city varchar(30),
-> details varchar(30)
-> );
Query OK, 0 rows affected (0.03 sec)
mysql> desc student3;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| country | varchar(30) | YES | | NULL | |
| province | varchar(30) | YES | | NULL | |
| city | varchar(30) | YES | | NULL | |
| details | varchar(30) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
6 rows in set (0.01 sec)
本次假设下面案例为 满 足 第 一 范 式 \color{red}{满足第一范式} 满足第一范式
mysql> insert into student3 values(1, '张三', '中国','四川省','成都市','武侯区武侯大道100号');
Query OK, 1 row affected (0.00 sec)
mysql> insert into student3 values(2, '张三', '中国','四川省','成都市','武侯区京城大道200号');
Query OK, 1 row affected (0.00 sec)
mysql> insert into student3 values(3, '张三', '中国','四川省','成都市','高新区天府大道90号');
Query OK, 1 row affected (0.00 sec)
mysql> select * from student3;
+----+--------+---------+-----------+-----------+-----------------------------+
| id | name | country | province | city | details |
+----+--------+---------+-----------+-----------+-----------------------------+
| 1 | 张三 | 中国 | 四川省 | 成都市 | 武侯区武侯大道100号 |
| 2 | 张三 | 中国 | 四川省 | 成都市 | 武侯区京城大道200号 |
| 3 | 张三 | 中国 | 四川省 | 成都市 | 高新区天府大道90号 |
+----+--------+---------+-----------+-----------+-----------------------------+
3 rows in set (0.00 sec)
范式,设计的越详细,对于某些实际操作可能更好,但是不一定都是好处。
address =====》 country | province | city | details
P17. 数据表设计-第二范式2NF
第二范式(2NF): 必 须 是 在 满 足 第 一 范 式 的 前 提 下 \color{red}{必须是在满足第一范式的前提下} 必须是在满足第一范式的前提下。
第二范式要求:除主键外的每一列都必须完全依赖于主键。
如果要出现不完全依赖,只可能发生在联合主键的情况下。
第二范式(2NF): 1 N F + 除 主 键 外 的 每 一 列 都 要 完 全 依 赖 于 主 键 。 \color{red}{1NF + 除主键外的每一列都要完全依赖于主键。} 1NF+除主键外的每一列都要完全依赖于主键。
说明备注:所有字段,都只能依赖于主键,不能依赖于其他字段,如(学号(主键),姓名,课程名称,成绩,学分) 不满足,课程名称不依赖学号
1.不满足2NF:订单表(联合主键,共同组成订单表的主键)
mysql> create table myorder(
-> product_id INT,
-> customer_id INT,
-> product_name VARCHAR(20),
-> customer_name VARCHAR(20),
-> PRIMARY KEY(product_id ,customer_id)
-> );
Query OK, 0 rows affected (0.08 sec)
mysql> desc myorder;
+---------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-------------+------+-----+---------+-------+
| product_id | int(11) | NO | PRI | NULL | |
| customer_id | int(11) | NO | PRI | NULL | |
| product_name | varchar(20) | YES | | NULL | |
| customer_name | varchar(20) | YES | | NULL | |
+---------------+-------------+------+-----+---------+-------+
4 rows in set (0.01 sec)
不 满 足 2 N F \color{red}{不满足2NF} 不满足2NF
product_id 只和 product_name 有关;
customer_id 只和 customer_name 有关。
出现了 联合主键,可能会出现一些列 只依赖于 主键的某一部分。
除主键以外的其它列,只依赖于主键的部分字段。
拆表:拆分 为 主表 和 副表
2. 拆表 ,使其满足 2NF
如下拆分成三个表,满足了第二范式的设计! !
订单表
mysql> create table myorder(
-> order_id int primary key,
-> product_id int, /*完全依赖于主键*/
-> customer_id int /*完全依赖于主键*/
-> );
Query OK, 0 rows affected (0.05 sec)
产品表
mysql> create table product(
-> id int primary key,
-> name varchar(20) /*完全依赖于主键*/
-> );
Query OK, 0 rows affected (0.03 sec)
客户表
mysql> create table customer(
-> id int primary key,
-> name varchar(20) /*完全依赖于主键*/
-> );
Query OK, 0 rows affected (0.03 sec)
P18. 数据表设计-第三范式 3NF
第三范式(3NF): 必 须 是 在 满 足 第 二 范 式 的 前 提 下 \color{red}{必须是在满足第二范式的前提下} 必须是在满足第二范式的前提下。
第二范式要求:除开主键列的其它列之间不能有传递依赖关系。
如果要出现不完全依赖,只可能发生在联合主键的情况下。
第二范式(3NF): 1 N F + 除 主 键 外 的 每 一 列 都 要 完 全 依 赖 于 主 键 。 \color{red}{1NF + 除主键外的每一列都要完全依赖于主键。} 1NF+除主键外的每一列都要完全依赖于主键。
备注说明:(学号) → (姓名, 年龄, 所在学院, 学院地点, 学院电话)不满足,因为
存在 (学号) → (所在学院) → (学院地点, 学院电话)
order_id 一 customer_id int 一 customer_phone,第一和第三有传递依赖关系
customer_phone varchar(15) /*customer_phone与order_id、customer_id有关系 ===》关系冗余! */
create table myorder(
order_id int primary key,
product_id int,
customer_id int, /*customer_phone与order_id有关系*/
customer_phone varchar(15) /*customer_phone与order_id、customer_id有关系 ===》关系冗余!*/
);
拆分如下:
-- 客户表
create table customer(
id int primary key,
name varchar(20), /*完全依赖于主键*/
phone varchar(15)
);
P19. 查询练习-数据准备
创建数据库
练习
- 创建数据库
selectTest
mysql> create database selectTest;
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| selecttest |
| sys |
| test |
+--------------------+
6 rows in set (0.00 sec)
创建数据表
学生表(student)
mysql> CREATE TABLE student(
-> sno VARCHAR(20) PRIMARY KEY,
-> sname VARCHAR(20) NOT NULL,
-> ssex VARCHAR(10) NOT NULL,
-> sbirthday DATETIME,
-> class VARCHAR(20)
-> );
Query OK, 0 rows affected (0.04 sec)
教师表(teacher)
mysql> CREATE TABLE teacher(
-> tno VARCHAR(20) PRIMARY KEY,
-> tname VARCHAR(20) NOT NULL,
-> tsex VARCHAR(20) NOT NULL,
-> tbirthday DATETIME,
-> prof VARCHAR(20) NOT NULL,
-> depart VARCHAR(20) NOT NULL
-> );
Query OK, 0 rows affected (0.03 sec)
课程表(course)
mysql> CREATE TABLE course(
-> cno VARCHAR(20) PRIMARY KEY,
-> cname VARCHAR(20) NOT NULL,
-> tno VARCHAR(20) NOT NULL,
-> FOREIGN KEY(tno) references teacher(tno)
-> );
Query OK, 0 rows affected (0.03 sec)
成绩表(score)
mysql> CREATE TABLE score (
-> sno VARCHAR(20) not null,
-> cno VARCHAR(20) not null,
-> degree decimal,
-> foreign key(sno) references student(sno),
-> foreign key(cno) references course(cno),
-> PRIMARY KEY(sno,cno)
-> );
Query OK, 0 rows affected (0.03 sec)
往数据表中添加数据
- 往数据表中添加数据
查看表数据
mysql> select * from student;
Empty set (0.02 sec)
mysql> select * from teacher;
Empty set (0.01 sec)
mysql> select * from course;
Empty set (0.01 sec)
mysql> select * from score;
Empty set (0.01 sec)
添加学生信息
mysql> INSERT INTO student VALUES('101','曾华','男','1977-09-01','95033');
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO student VALUES('102','匡明','男','1975-10-02','95031');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO student VALUES('103','王丽','女','1976-01-23','95033');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO student VALUES('104','李军','男','1976-02-20','95033');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO student VALUES('105','王芳','女','1975-02-10','95031');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO student VALUES('106','陆军','男','1974-06-03','95031');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO student VALUES('107','王尼玛','男','1976-02-20','95033');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO student VALUES('108','张全蛋','男','1975-02-10','95031');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO student VALUES('109','赵铁柱','男','1974-06-03','95031');
Query OK, 1 row affected (0.00 sec)
mysql> select * from student;
+-----+-----------+------+---------------------+-------+
| sno | sname | ssex | sbirthday | class |
+-----+-----------+------+---------------------+-------+
| 101 | 曾华 | 男 | 1977-09-01 00:00:00 | 95033 |
| 102 | 匡明 | 男 | 1975-10-02 00:00:00 | 95031 |
| 103 | 王丽 | 女 | 1976-01-23 00:00:00 | 95033 |
| 104 | 李军 | 男 | 1976-02-20 00:00:00 | 95033 |
| 105 | 王芳 | 女 | 1975-02-10 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 00:00:00 | 95031 |
| 107 | 王尼玛 | 男 | 1976-02-20 00:00:00 | 95033 |
| 108 | 张全蛋 | 男 | 1975-02-10 00:00:00 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 00:00:00 | 95031 |
+-----+-----------+------+---------------------+-------+
9 rows in set (0.00 sec)
添加教师信息
mysql> INSERT INTO teacher VALUES('804','李诚','男','1958-12-02','副教授','计算机系');
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO teacher VALUES('856','张旭','男','1969-03-12','讲师','电子工程系');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO teacher VALUES('825','王萍','女','1972-05-05','助教','计算机系');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO teacher VALUES('831','刘冰','女','1977-08-14','助教','电子工程系');
Query OK, 1 row affected (0.01 sec)
mysql> select * from teacher;
+-----+--------+------+---------------------+-----------+-----------------+
| tno | tname | tsex | tbirthday | prof | depart |
+-----+--------+------+---------------------+-----------+-----------------+
| 804 | 李诚 | 男 | 1958-12-02 00:00:00 | 副教授 | 计算机系 |
| 825 | 王萍 | 女 | 1972-05-05 00:00:00 | 助教 | 计算机系 |
| 831 | 刘冰 | 女 | 1977-08-14 00:00:00 | 助教 | 电子工程系 |
| 856 | 张旭 | 男 | 1969-03-12 00:00:00 | 讲师 | 电子工程系 |
+-----+--------+------+---------------------+-----------+-----------------+
4 rows in set (0.00 sec)
添加课程信息
mysql> INSERT INTO course VALUES('3-105','计算机导论','825');
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO course VALUES('3-245','操作系统','804');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO course VALUES('6-166','数字电路','856');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO course VALUES('9-888','高等数学','831');
Query OK, 1 row affected (0.01 sec)
mysql> select * from course;
+-------+-----------------+-----+
| cno | cname | tno |
+-------+-----------------+-----+
| 3-105 | 计算机导论 | 825 |
| 3-245 | 操作系统 | 804 |
| 6-166 | 数字电路 | 856 |
| 9-888 | 高等数学 | 831 |
+-------+-----------------+-----+
4 rows in set (0.00 sec)
添加成绩信息
mysql> INSERT INTO score VALUES('103','3-245','86');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO score VALUES('105','3-245','75');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO score VALUES('109','3-245','68');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO score VALUES('103','3-105','92');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO score VALUES('105','3-105','88');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO score VALUES('109','3-105','76');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO score VALUES('103','6-166','85');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO score VALUES('105','6-166','79');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO score VALUES('109','6-166','81');
Query OK, 1 row affected (0.02 sec)
mysql> select * from score;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-105 | 92 |
| 103 | 3-245 | 86 |
| 103 | 6-166 | 85 |
| 105 | 3-105 | 88 |
| 105 | 3-245 | 75 |
| 105 | 6-166 | 79 |
| 109 | 3-105 | 76 |
| 109 | 3-245 | 68 |
| 109 | 6-166 | 81 |
+-----+-------+--------+
9 rows in set (0.00 sec)
P20. 查询练习 - 1 到 10
- 查询数据表的所有数据。
select * from 表名;
- 查询数据表中指定列的全部数据,如列一、列二和列三
select 字段1, 字段2, 字段3 from 表名;
- 查询数据表中指定列的不重复的全部数据
select distinct 字段1 from 表名;
- 查询范围:表中字段1在60到80之间的全部数据
select * from 表名 where 字段1 between 60 and 80;
(查询区间:between…and… 闭区间 [min, max])
select * from 表名 where 字段1 > 60 and 字段1 < 80;
- 查询数据表中某字段值为value1,value2或value2的全部数据
select * from 表名 where 字段1 in(value1, value2, value3);
- 查询数据表表中条件1或条件2的全部数据
select * from 表名 where 字段1 = '值1' or 字段2 = '值2';
- 以某字段降序、升序查询数据表的全部数据
select * from 表名 order by 排序字段 desc;
select * from 表名 order by 排序字段 asc;
(排序字段后省略为默认升序效果)- 以字段1升序、 字段2降序查询数据表的全部数据
select * from 表名 order by 字段1 asc, 字段2 desc;
- 查询字段1值为“值1"的数量
select count(*) from 数据表 where 字段1= '值1';
- 查询数据表中的最大值(字段1的最高最大值)的字段2和字段3数据。(子查询或者排序)
子查询
select 字段2, 子弹3 from 数据表 where 字段1=(select max(字段1) from 数据表);
排序(排序无法用于并列值的情况)
limit 数值1,数值2 分隔,表示从多少开始,操作多少条
如,
select 字段2, 子弹3 from 数据表 order by 字段1 desc limit 0,1;
(第一位开始,第一名,即最大值)
select 字段2, 子弹3 from 数据表 order by 字段1 desc limit 0,2;
(第二位开始,前两名)- 查询所有字段1 的字段2的平均数
select 字段1, avg(字段2) from score group by 字段1;
- 查询数据表中至少有2名学生选修的并以3开头的课程的平均分数
select cno, avg(degree), count(*) from 表名 group by cno having count(sno) >=2 and cno like '3%';
- 范围查询:查询分数大于70,小于90的sno列。
select sno, degree from score where degree > 70 and degree < 90;
select sno, degree from score where degree between 70 and 90;
- 两个表关联查询:查询所有学生的sname(表1)、cno(表2)和degree(表2)列。
select sname, cno, degree from 表1, 表2 where 表1.字段1= 表2.字段1;
- 两个表关联查询:查询所有学生的字段1(表1)、字段2(表2)和字段3(表2)列。
select 字段1, 字段2, 字段3 from 表1, 表2 where 表1.同字段1 = 表2.同字段1;
- 三表关联查询:查询所有学生的字段1(表1)、字段2(表2)和字段3(表3)列。
select 字段1, 字段2, 字段3 from 表1,表2, 表3 where 表1.同字段1= 表2.同字段2 and 表2.同字段3= 表3.同字段4;
- 查询"95031"班学生每课的平均分。
select 课程,avg(分数) from 成绩表 where 学生 in (select 学生 from student where 班级='95031') group by 课程;
- 查询选修“3-105"课程的成绩高于“109”号同学“3-105"成绩的所有同学的记录。
select * from score where cno = '3-105' and degree > ( select degree from score where sno = '109' and cno = '3-105');
- 查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。
select * from score where degree > ( select degree from score where sno = '109' and cno = '3-105');
- 查询和学号为108、101的同学,同年出生的所有学生的sno、sname和sbirthday列。
select sno, sname, sbirthday from student where year(sbirthday) in (select year(sbirthday) from student where sno in ('108', '101'));
- 查询“张旭“教师任课的学生成绩。
select * from score where cno in (select cno from course where tno in (select tno from teacher where tname = '张旭'));
查询练习
- 查询student表的所有记录。
mysql> select * from student;
+-----+-----------+------+---------------------+-------+
| sno | sname | ssex | sbirthday | class |
+-----+-----------+------+---------------------+-------+
| 101 | 曾华 | 男 | 1977-09-01 00:00:00 | 95033 |
| 102 | 匡明 | 男 | 1975-10-02 00:00:00 | 95031 |
| 103 | 王丽 | 女 | 1976-01-23 00:00:00 | 95033 |
| 104 | 李军 | 男 | 1976-02-20 00:00:00 | 95033 |
| 105 | 王芳 | 女 | 1975-02-10 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 00:00:00 | 95031 |
| 107 | 王尼玛 | 男 | 1976-02-20 00:00:00 | 95033 |
| 108 | 张全蛋 | 男 | 1975-02-10 00:00:00 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 00:00:00 | 95031 |
+-----+-----------+------+---------------------+-------+
9 rows in set (0.00 sec)
- 查询student表中的所有记录的sname、ssex和class列。
mysql> select sname, ssex, class from student;
+-----------+------+-------+
| sname | ssex | class |
+-----------+------+-------+
| 曾华 | 男 | 95033 |
| 匡明 | 男 | 95031 |
| 王丽 | 女 | 95033 |
| 李军 | 男 | 95033 |
| 王芳 | 女 | 95031 |
| 陆军 | 男 | 95031 |
| 王尼玛 | 男 | 95033 |
| 张全蛋 | 男 | 95031 |
| 赵铁柱 | 男 | 95031 |
+-----------+------+-------+
9 rows in set (0.01 sec)
- 查询教师所有的单位,即不重复的depart列。
mysql> select depart from teacher;
+-----------------+
| depart |
+-----------------+
| 计算机系 |
| 计算机系 |
| 电子工程系 |
| 电子工程系 |
+-----------------+
4 rows in set (0.00 sec)
mysql> select distinct depart from teacher;
+-----------------+
| depart |
+-----------------+
| 计算机系 |
| 电子工程系 |
+-----------------+
2 rows in set (0.00 sec)
- 查询score表中成绩在60到80之间的所有记录。
mysql> select * from score where degree between 60 and 80;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 105 | 3-245 | 75 |
| 105 | 6-166 | 79 |
| 109 | 3-105 | 76 |
| 109 | 3-245 | 68 |
+-----+-------+--------+
4 rows in set (0.00 sec)
mysql> select * from score where degree >= 60 and degree <= 80;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 105 | 3-245 | 75 |
| 105 | 6-166 | 79 |
| 109 | 3-105 | 76 |
| 109 | 3-245 | 68 |
+-----+-------+--------+
4 rows in set (0.00 sec)
- 查询score表中成绩为85,86或88的记录。
表示或者关系的查询(in)
mysql> select * from score where degree in(85, 86, 88);
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-245 | 86 |
| 103 | 6-166 | 85 |
| 105 | 3-105 | 88 |
+-----+-------+--------+
3 rows in set (0.00 sec)
- 查询student表中“95031”班或性别为“女”的同学记录。
mysql> select * from student where class = '95031' or sex = '女';
+-----+-----------+------+---------------------+-------+
| sno | sname | sex | sbirthday | class |
+-----+-----------+------+---------------------+-------+
| 102 | 匡明 | 男 | 1975-10-02 00:00:00 | 95031 |
| 103 | 王丽 | 女 | 1976-01-23 00:00:00 | 95033 |
| 105 | 王芳 | 女 | 1975-02-10 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 00:00:00 | 95031 |
| 108 | 张全蛋 | 男 | 1975-02-10 00:00:00 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 00:00:00 | 95031 |
+-----+-----------+------+---------------------+-------+
6 rows in set (0.00 sec)
- 以class降序查询student表的所有记录
– 降序(desc)
mysql> select * from student order by class desc;
+-----+-----------+------+---------------------+-------+
| sno | sname | sex | sbirthday | class |
+-----+-----------+------+---------------------+-------+
| 101 | 曾华 | 男 | 1977-09-01 00:00:00 | 95033 |
| 103 | 王丽 | 女 | 1976-01-23 00:00:00 | 95033 |
| 104 | 李军 | 男 | 1976-02-20 00:00:00 | 95033 |
| 107 | 王尼玛 | 男 | 1976-02-20 00:00:00 | 95033 |
| 102 | 匡明 | 男 | 1975-10-02 00:00:00 | 95031 |
| 105 | 王芳 | 女 | 1975-02-10 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 00:00:00 | 95031 |
| 108 | 张全蛋 | 男 | 1975-02-10 00:00:00 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 00:00:00 | 95031 |
+-----+-----------+------+---------------------+-------+
9 rows in set (0.00 sec)
order by 默认效果是升序
不写等同于asc
mysql> select * from student order by class;
+-----+-----------+------+---------------------+-------+
| sno | sname | sex | sbirthday | class |
+-----+-----------+------+---------------------+-------+
| 102 | 匡明 | 男 | 1975-10-02 00:00:00 | 95031 |
| 105 | 王芳 | 女 | 1975-02-10 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 00:00:00 | 95031 |
| 108 | 张全蛋 | 男 | 1975-02-10 00:00:00 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 00:00:00 | 95031 |
| 101 | 曾华 | 男 | 1977-09-01 00:00:00 | 95033 |
| 103 | 王丽 | 女 | 1976-01-23 00:00:00 | 95033 |
| 104 | 李军 | 男 | 1976-02-20 00:00:00 | 95033 |
| 107 | 王尼玛 | 男 | 1976-02-20 00:00:00 | 95033 |
+-----+-----------+------+---------------------+-------+
9 rows in set (0.00 sec)
–升序(asc)
mysql> select * from student order by class asc;
+-----+-----------+------+---------------------+-------+
| sno | sname | sex | sbirthday | class |
+-----+-----------+------+---------------------+-------+
| 102 | 匡明 | 男 | 1975-10-02 00:00:00 | 95031 |
| 105 | 王芳 | 女 | 1975-02-10 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 00:00:00 | 95031 |
| 108 | 张全蛋 | 男 | 1975-02-10 00:00:00 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 00:00:00 | 95031 |
| 101 | 曾华 | 男 | 1977-09-01 00:00:00 | 95033 |
| 103 | 王丽 | 女 | 1976-01-23 00:00:00 | 95033 |
| 104 | 李军 | 男 | 1976-02-20 00:00:00 | 95033 |
| 107 | 王尼玛 | 男 | 1976-02-20 00:00:00 | 95033 |
+-----+-----------+------+---------------------+-------+
9 rows in set (0.00 sec)
- 以cno升序、 degree降序查询score表的所有记录。
mysql> select * from score order by cno asc, degree desc;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-105 | 92 |
| 105 | 3-105 | 88 |
| 109 | 3-105 | 76 |
| 103 | 3-245 | 86 |
| 105 | 3-245 | 75 |
| 109 | 3-245 | 68 |
| 103 | 6-166 | 85 |
| 109 | 6-166 | 81 |
| 105 | 6-166 | 79 |
| 101 | 9-888 | 80 |
+-----+-------+--------+
10 rows in set (0.01 sec)
- 查询“95031"班的学生人数。
mysql> select count(*) from student where class = '95031';
+----------+
| count(*) |
+----------+
| 5 |
+----------+
1 row in set (0.00 sec)
mysql> select * from student where class = '95031';
+-----+-----------+------+---------------------+-------+
| sno | sname | sex | sbirthday | class |
+-----+-----------+------+---------------------+-------+
| 102 | 匡明 | 男 | 1975-10-02 00:00:00 | 95031 |
| 105 | 王芳 | 女 | 1975-02-10 00:00:00 | 95031 |
| 106 | 陆军 | 男 | 1974-06-03 00:00:00 | 95031 |
| 108 | 张全蛋 | 男 | 1975-02-10 00:00:00 | 95031 |
| 109 | 赵铁柱 | 男 | 1974-06-03 00:00:00 | 95031 |
+-----+-----------+------+---------------------+-------+
5 rows in set (0.00 sec)
- 查询score表中的最高分的学生学号和课程号。(子查询或者排序)
子查询做法:
mysql> select sno, cno from score where degree =(select max(degree) from score);
+-----+-------+
| sno | cno |
+-----+-------+
| 103 | 3-105 |
+-----+-------+
1 row in set (0.01 sec)
- 找到最高分
select max(degree) from score
- 找最高分的 sno 和 cno
select sno, cno from score where degree =(select max(degree) from score);
排序的做法:、
mysql> select * from course;
+-------+-----------------+-----+
| cno | cname | tno |
+-------+-----------------+-----+
| 3-105 | 计算机导论 | 825 |
| 3-245 | 操作系统 | 804 |
| 6-166 | 数字电路 | 856 |
| 9-888 | 高等数学 | 831 |
+-------+-----------------+-----+
4 rows in set (0.00 sec)
mysql> select sno, cno, degree from score order by degree desc limit 0,1;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-105 | 92 |
+-----+-------+--------+
1 row in set (0.00 sec)
mysql> select sno, cno, degree from score order by degree desc limit 0,2;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-105 | 92 |
| 105 | 3-105 | 88 |
+-----+-------+--------+
2 rows in set (0.00 sec)
mysql> select sno, cno, degree from score order by degree desc limit 1,2;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 105 | 3-105 | 88 |
| 103 | 3-245 | 86 |
+-----+-------+--------+
2 rows in set (0.00 sec)
mysql> select sno, cno, degree from score order by degree desc;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-105 | 92 |
| 105 | 3-105 | 88 |
| 103 | 3-245 | 86 |
| 103 | 6-166 | 85 |
| 109 | 6-166 | 81 |
| 101 | 9-888 | 80 |
| 105 | 6-166 | 79 |
| 109 | 3-105 | 76 |
| 105 | 3-245 | 75 |
| 109 | 3-245 | 68 |
+-----+-------+--------+
10 rows in set (0.00 sec)
22. 查询练习-分组计算平均成绩
11、查询每门课的平均成绩
mysql> select avg(degree) from score where cno= '3-245';
+-------------+
| avg(degree) |
+-------------+
| 76.3333 |
+-------------+
1 row in set (0.01 sec)
mysql> select avg(degree) from score where cno= '6-166';
+-------------+
| avg(degree) |
+-------------+
| 81.6667 |
+-------------+
1 row in set (0.00 sec)
mysql> select avg(degree) from score where cno= '9-888';
+-------------+
| avg(degree) |
+-------------+
| 80.0000 |
+-------------+
1 row in set (0.00 sec)
mysql> select avg(degree) from score group by cno;
+-------------+
| avg(degree) |
+-------------+
| 85.3333 |
| 76.3333 |
| 81.6667 |
| 80.0000 |
+-------------+
4 rows in set (0.00 sec)
能不能够在一个SQL语句中写呢?(group by 分组)
mysql> select cno, avg(degree) from score group by cno;
+-------+-------------+
| cno | avg(degree) |
+-------+-------------+
| 3-105 | 85.3333 |
| 3-245 | 76.3333 |
| 6-166 | 81.6667 |
| 9-888 | 80.0000 |
+-------+-------------+
4 rows in set (0.00 sec)
23. 查询练习-分组条件与模糊查询
12、查询score表中至少有2名学生选修的并以3开头的课程的平均分数。
mysql> select cno, avg(degree), count(*) from score group by cno;
+-------+-------------+----------+
| cno | avg(degree) | count(*) |
+-------+-------------+----------+
| 3-105 | 85.3333 | 3 |
| 3-245 | 76.3333 | 3 |
| 6-166 | 81.6667 | 3 |
| 9-888 | 80.0000 | 1 |
+-------+-------------+----------+
4 rows in set (0.00 sec)
mysql> select cno, avg(degree), count(*) from score group by cno having count(sno) >=2;
+-------+-------------+----------+
| cno | avg(degree) | count(*) |
+-------+-------------+----------+
| 3-105 | 85.3333 | 3 |
| 3-245 | 76.3333 | 3 |
| 6-166 | 81.6667 | 3 |
+-------+-------------+----------+
3 rows in set (0.00 sec)
mysql> select cno, avg(degree), count(*) from score group by cno having count(sno) >=2 and cno like '3%';
+-------+-------------+----------+
| cno | avg(degree) | count(*) |
+-------+-------------+----------+
| 3-105 | 85.3333 | 3 |
| 3-245 | 76.3333 | 3 |
+-------+-------------+----------+
2 rows in set (0.00 sec)
24. 查询练习-范围查询的两种方式
13、查询分数大于70,小于90的sno列。
mysql> select sno, degree from score where degree > 70 and degree < 90;
+-----+--------+
| sno | degree |
+-----+--------+
| 101 | 80 |
| 103 | 86 |
| 103 | 85 |
| 105 | 88 |
| 105 | 75 |
| 105 | 79 |
| 109 | 76 |
| 109 | 81 |
+-----+--------+
8 rows in set (0.00 sec)
mysql> select sno, degree from score where degree between 70 and 90;
+-----+--------+
| sno | degree |
+-----+--------+
| 101 | 80 |
| 103 | 86 |
| 103 | 85 |
| 105 | 88 |
| 105 | 75 |
| 105 | 79 |
| 109 | 76 |
| 109 | 81 |
+-----+--------+
8 rows in set (0.00 sec)
25. 查询练习-多表查询
14、查询所有学生的sname、cno和degree列。
mysql> select sno, sname from student;
+-----+-----------+
| sno | sname |
+-----+-----------+
| 101 | 曾华 |
| 102 | 匡明 |
| 103 | 王丽 |
| 104 | 李军 |
| 105 | 王芳 |
| 106 | 陆军 |
| 107 | 王尼玛 |
| 108 | 张全蛋 |
| 109 | 赵铁柱 |
+-----+-----------+
9 rows in set (0.00 sec)
mysql> select sno, cno, degree from score;
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 101 | 9-888 | 80 |
| 103 | 3-105 | 92 |
| 103 | 3-245 | 86 |
| 103 | 6-166 | 85 |
| 105 | 3-105 | 88 |
| 105 | 3-245 | 75 |
| 105 | 6-166 | 79 |
| 109 | 3-105 | 76 |
| 109 | 3-245 | 68 |
| 109 | 6-166 | 81 |
+-----+-------+--------+
10 rows in set (0.00 sec)
mysql> select sname, cno, degree from student, score
-> where student.sno = score.sno;
+-----------+-------+--------+
| sname | cno | degree |
+-----------+-------+--------+
| 曾华 | 9-888 | 80 |
| 王丽 | 3-105 | 92 |
| 王丽 | 3-245 | 86 |
| 王丽 | 6-166 | 85 |
| 王芳 | 3-105 | 88 |
| 王芳 | 3-245 | 75 |
| 王芳 | 6-166 | 79 |
| 赵铁柱 | 3-105 | 76 |
| 赵铁柱 | 3-245 | 68 |
| 赵铁柱 | 6-166 | 81 |
+-----------+-------+--------+
10 rows in set (0.01 sec)
26. 查询练习-多表查询
15、查询所有学生的sno、cname和degree列。
mysql> select cno, cname from course;
+-------+-----------------+
| cno | cname |
+-------+-----------------+
| 3-105 | 计算机导论 |
| 3-245 | 操作系统 |
| 6-166 | 数字电路 |
| 9-888 | 高等数学 |
+-------+-----------------+
4 rows in set (0.00 sec)
mysql> select cno, sno, degree from score;
+-------+-----+--------+
| cno | sno | degree |
+-------+-----+--------+
| 9-888 | 101 | 80 |
| 3-105 | 103 | 92 |
| 3-245 | 103 | 86 |
| 6-166 | 103 | 85 |
| 3-105 | 105 | 88 |
| 3-245 | 105 | 75 |
| 6-166 | 105 | 79 |
| 3-105 | 109 | 76 |
| 3-245 | 109 | 68 |
| 6-166 | 109 | 81 |
+-------+-----+--------+
10 rows in set (0.00 sec)
mysql> select sno, cname, degree from score, course
-> where score.cno = course.cno;
+-----+-----------------+--------+
| sno | cname | degree |
+-----+-----------------+--------+
| 101 | 高等数学 | 80 |
| 103 | 计算机导论 | 92 |
| 103 | 操作系统 | 86 |
| 103 | 数字电路 | 85 |
| 105 | 计算机导论 | 88 |
| 105 | 操作系统 | 75 |
| 105 | 数字电路 | 79 |
| 109 | 计算机导论 | 76 |
| 109 | 操作系统 | 68 |
| 109 | 数字电路 | 81 |
+-----+-----------------+--------+
10 rows in set (0.01 sec)
27. 查询练习-三表关联查询
16、查询所有学生的sname(student表)、cname(course表)和degree(score表)列。
mysql> select sname, cname, degree from student,course, score
-> where student.sno = score.sno
-> and course.cno = score.cno;
+-----------+-----------------+--------+
| sname | cname | degree |
+-----------+-----------------+--------+
| 曾华 | 高等数学 | 80 |
| 王丽 | 计算机导论 | 92 |
| 王丽 | 操作系统 | 86 |
| 王丽 | 数字电路 | 85 |
| 王芳 | 计算机导论 | 88 |
| 王芳 | 操作系统 | 75 |
| 王芳 | 数字电路 | 79 |
| 赵铁柱 | 计算机导论 | 76 |
| 赵铁柱 | 操作系统 | 68 |
| 赵铁柱 | 数字电路 | 81 |
+-----------+-----------------+--------+
10 rows in set (0.03 sec)
mysql> select sname, cname, degree,student.sno, course.cno from student,course, score
-> where student.sno = score.sno
-> and course.cno = score.cno;
+-----------+-----------------+--------+-----+-------+
| sname | cname | degree | sno | cno |
+-----------+-----------------+--------+-----+-------+
| 曾华 | 高等数学 | 80 | 101 | 9-888 |
| 王丽 | 计算机导论 | 92 | 103 | 3-105 |
| 王丽 | 操作系统 | 86 | 103 | 3-245 |
| 王丽 | 数字电路 | 85 | 103 | 6-166 |
| 王芳 | 计算机导论 | 88 | 105 | 3-105 |
| 王芳 | 操作系统 | 75 | 105 | 3-245 |
| 王芳 | 数字电路 | 79 | 105 | 6-166 |
| 赵铁柱 | 计算机导论 | 76 | 109 | 3-105 |
| 赵铁柱 | 操作系统 | 68 | 109 | 3-245 |
| 赵铁柱 | 数字电路 | 81 | 109 | 6-166 |
+-----------+-----------------+--------+-----+-------+
10 rows in set (0.00 sec)
找出相等字段
mysql> select sname, cname, degree,student.sno as stu_sno, score.sno, course.cno as cou_cno, score.cno from student,course, score
-> where student.sno = score.sno
-> and course.cno = score.cno;
+-----------+-----------------+--------+---------+-----+---------+-------+
| sname | cname | degree | stu_sno | sno | cou_cno | cno |
+-----------+-----------------+--------+---------+-----+---------+-------+
| 曾华 | 高等数学 | 80 | 101 | 101 | 9-888 | 9-888 |
| 王丽 | 计算机导论 | 92 | 103 | 103 | 3-105 | 3-105 |
| 王丽 | 操作系统 | 86 | 103 | 103 | 3-245 | 3-245 |
| 王丽 | 数字电路 | 85 | 103 | 103 | 6-166 | 6-166 |
| 王芳 | 计算机导论 | 88 | 105 | 105 | 3-105 | 3-105 |
| 王芳 | 操作系统 | 75 | 105 | 105 | 3-245 | 3-245 |
| 王芳 | 数字电路 | 79 | 105 | 105 | 6-166 | 6-166 |
| 赵铁柱 | 计算机导论 | 76 | 109 | 109 | 3-105 | 3-105 |
| 赵铁柱 | 操作系统 | 68 | 109 | 109 | 3-245 | 3-245 |
| 赵铁柱 | 数字电路 | 81 | 109 | 109 | 6-166 | 6-166 |
+-----------+-----------------+--------+---------+-----+---------+-------+
10 rows in set (0.00 sec)
28. 查询练习-子查询 加 分组求平均分
17、查询"95031"班学生每课的平均分。
mysql> select * from student where class ='95031';
mysql> select sno from student where class ='95031';
mysql> select * from score where sno in (select sno from student where class ='95031');
mysql> select * from score where sno in (select sno from student where class ='95031');
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 105 | 3-105 | 88 |
| 105 | 3-245 | 75 |
| 105 | 6-166 | 79 |
| 109 | 3-105 | 76 |
| 109 | 3-245 | 68 |
| 109 | 6-166 | 81 |
+-----+-------+--------+
6 rows in set (0.00 sec)
mysql> select cno,avg(degree)
-> from score
-> where sno in (select sno from student where class ='95031')
-> group by cno;
+-------+-------------+
| cno | avg(degree) |
+-------+-------------+
| 3-105 | 82.0000 |
| 3-245 | 71.5000 |
| 6-166 | 80.0000 |
+-------+-------------+
3 rows in set (0.00 sec)
29. 查询练习-子查询
18、查询选修“3-105"课程的成绩高于“109”号同学“3-105"成绩的所有同学的记录。
mysql> select degree from score where sno = '109' and cno = '3-105';
mysql> select * from score where degree > ( select degree from score where sno = '109' and cno = '3-105');
mysql> select * from score where cno = '3-105' and degree > ( select degree from score where sno = '109' and cno = '3-105');
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 3-105 | 92 |
| 105 | 3-105 | 88 |
+-----+-------+--------+
2 rows in set (0.00 sec)
30. 查询练习-子查询
19、查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。
mysql> select * from score where sno = '109' and cno = '3-105';
mysql> select degree from score where sno = '109' and cno = '3-105';
mysql> select * from score where degree > ( select degree from score where sno = '109' and cno = '3-105');
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 101 | 9-888 | 80 |
| 103 | 3-105 | 92 |
| 103 | 3-245 | 86 |
| 103 | 6-166 | 85 |
| 105 | 3-105 | 88 |
| 105 | 6-166 | 79 |
| 109 | 6-166 | 81 |
+-----+-------+--------+
7 rows in set (0.00 sec)
31. 查询练习year函数与带in关键字的子查询
20、查询和学号为108、101的同学,同年出生的所有学生的sno、sname和sbirthday列。
mysql> select * from student where sno in ('108', '101');
mysql> select year(sbirthday) from student where sno in ('108', '101');
mysql> select * from student where year(sbirthday) in (select year(sbirthday) from student where sno in ('108', '101'));
mysql> select sno, sname, sbirthday from student where year(sbirthday) in (select year(sbirthday) from student where sno in ('108', '101'));
+-----+-----------+---------------------+
| sno | sname | sbirthday |
+-----+-----------+---------------------+
| 101 | 曾华 | 1977-09-01 00:00:00 |
| 102 | 匡明 | 1975-10-02 00:00:00 |
| 105 | 王芳 | 1975-02-10 00:00:00 |
| 108 | 张全蛋 | 1975-02-10 00:00:00 |
+-----+-----------+---------------------+
4 rows in set (0.00 sec)
32. 查询练习-多层嵌套子查询
21、查询“张旭“教师任课的学生成绩。
mysql> select * from teacher where tname = '张旭';
mysql> select tno from teacher where tname = '张旭';
mysql> select * from course where tno in (select tno from teacher where tname = '张旭');
mysql> select cno from course where tno in (select tno from teacher where tname = '张旭');
mysql> select * from score where cno in (select cno from course where tno in (select tno from teacher where tname = '张旭'));
+-----+-------+--------+
| sno | cno | degree |
+-----+-------+--------+
| 103 | 6-166 | 85 |
| 105 | 6-166 | 79 |
| 109 | 6-166 | 81 |
+-----+-------+--------+
3 rows in set (0.00 sec)