MySQL多表查询实训
实训1
实践需求1:查询张三当前借阅的图书信息,图书信息只需显示借阅人编号、借阅人名称、图书名称和借阅时间。
动手实践1:根据图书表book的borrower_id字段和用户表user的name字段将表book和表user进行关联,并查询出user表中name值为张三的记录,查询出的记录只返回user表的id、name字段的值,以及book表的 borrower、name、bookname、b.borrow_time字段的值,具体的SQL语句如下所示。
SELECT u.id,u.name borrower,b.name bookname,b.borrow_time FROM book b,user u
WHERE b.borrower_id=u.id AND u.name='张三';
实践需求2:查询价格比《西游记》的价格高的图书信息,图书信息只需显示图书名称和图书价格。
动手实践2:首先查询图书表book中name的值为西游记的图书价格,将该查询作为子查询;然后查询价格大于子查询结果的图书信息,查询出的图书信息只返回name、price字段的值,具体的SQL语句如下所示。
SELECT name,price FROM book
WHERE price>(SELECT price FROM book WHERE name='西游记');
实践需求3:查询高于平均价的图书信息。查询价格比所有图书的平均价格还低的图书信息,图书信息只需显示图书名称和图书价格。
动手实践3:首先查询图书表book中price字段的平均值,将该查询作为子查询;然后查询价格小于于子查询结果的图书信息,查询出的图书信息只返回name、price字段的值,具体的SQL语句如下所示。
SELECT name,price FROM book
WHERE price<(SELECT AVG(price) FROM book);
实践需求4:根据图书状态查询同类状态的图书。查询图书状态和《三国演义》相同的图书信息,图书信息只需显示图书名称、图书价格和状态。
动手实践4:首先查询图书表book中三国演义state的值,将该查询作为子查询;然后查询book表中state值和子查询结果相同的图书信息,查询出的图书信息只返回name、price、state字段的值,具体的SQL语句如下所示。
SELECT name,price,state FROM book
WHERE state=(SELECT state FROM book WHERE name='三国演义');
实践需求5:查询已借阅的低于某价格的图书信息。查询已借阅图书中,价格比任意未借阅的图书价格还低的图书信息,图书信息只需显示图书名称、图书价格和状态。
动手实践5:首先查询图书表book中state等于0的图书价格,将该查询作为子查询;然后查询book表中state值等于1,并且price字段的值小于任意一个子查询结果的图书信息,查询出的图书信息只返回name、price、state字段的值,具体的SQL语句如下所示。
SELECT name,price,state FROM book
WHERE state=1 AND price<ANY(SELECT price FROM book WHERE state=0);
实践需求6:查询价格比任意已借阅的图书价格还高的图书信息,图书信息只需显示图书名称、图书价格和状态。
动手实践6:首先查询图书表book中state等于1的图书价格,将该查询作为子查询;然后查询book表中price字段的值大于所有子查询结果的图书信息,查询出的图书信息只返回name、price、state字段的值,具体的SQL语句如下所示。
SELECT name,price,state FROM book
WHERE price>ALL(SELECT price FROM book WHERE state=1);
实践需求7:添加外键约束,对图书表中的借阅者编号添加外键约束,以保证数据的完整性。
动手实践7:在图书表book中borrower_id字段添加外键约束,创建的外键引用user表的id字段,具体的SQL语句如下所示。
ALTER TABLE book ADD CONSTRAINT FK_ID FOREIGN KEY(borrower_id)
REFERENCES user (id);
本章主要对多表操作进行了详细讲解。首先对多表查询进行了介绍,其次讲解了子查询,然后讲解了外键约束;最后通过上机实践案例,加深读者对多表操作的熟练度。通过本章的学习,希望读者能够掌握多表操作的基本使用,为后续的学习打下坚实的基础。
mysql> select * from user;
+----+------+-------+
| id | name | state |
+----+------+-------+
| 1 | 张三 | 0 |
| 2 | 李四 | 0 |
+----+------+-------+
2 rows in set (0.00 sec)
mysql> select * from book\G;
*************************** 1. row ***************************
id: 1
bookname: 三国演义
price: 62.10
upload_time: 2024-05-23 08:07:01
borrower_id: NULL
borrow_time: NULL
state: 2
*************************** 2. row ***************************
id: 2
bookname: MySQL数据库入门
price: 36.00
upload_time: 2024-05-23 08:07:01
borrower_id: 1
borrow_time: 2024-05-28 11:14:47
state: 1
*************************** 3. row ***************************
id: 3
bookname: JavaWeb程序开发入门
price: 44.10
upload_time: 2024-05-23 08:07:01
borrower_id: NULL
borrow_time: NULL
state: 0
*************************** 4. row ***************************
id: 4
bookname: 西游记
price: 53.10
upload_time: 2024-05-23 08:07:01
borrower_id: NULL
borrow_time: NULL
state: 0
*************************** 5. row ***************************
id: 5
bookname: 红楼梦
price: 29.70
upload_time: 2024-05-23 08:07:01
borrower_id: NULL
borrow_time: NULL
state: 2
*************************** 6. row ***************************
id: 6
bookname: Java基础入门(第3版)
price: 53.10
upload_time: 2024-05-23 08:07:01
borrower_id: NULL
borrow_time: NULL
state: 0
*************************** 7. row ***************************
id: 7
bookname: 水浒传
price: 66.00
upload_time: 2024-05-23 08:07:01
borrower_id: NULL
borrow_time: NULL
state: 2
7 rows in set (0.00 sec)
ERROR:
No query specified
mysql> select u.id,u.name,b.borrower,b.bookname,b.borrow_time from book as b,use
r as u where b.borrower_id=u.id;
ERROR 1054 (42S22): Unknown column 'b.borrower' in 'field list'
mysql> select u.id,u.name,b.borrower_id,b.bookname,b.borrow_time from book as b,
user as u where b.borrower_id=u.id;
+----+------+-------------+-----------------+---------------------+
| id | name | borrower_id | bookname | borrow_time |
+----+------+-------------+-----------------+---------------------+
| 1 | 张三 | 1 | MySQL数据库入门 | 2024-05-28 11:14:47 |
+----+------+-------------+-----------------+---------------------+
1 row in set (0.02 sec)
mysql> select b.bookname,b.price from book as b where price>(select price from b
ook where name='西游记');
ERROR 1054 (42S22): Unknown column 'name' in 'where clause'
mysql> select b.bookname,b.price from book as b where price>(select price from b
ook where bookname='西游记');
+----------+-------+
| bookname | price |
+----------+-------+
| 三国演义 | 62.10 |
| 水浒传 | 66.00 |
+----------+-------+
2 rows in set (0.00 sec)
mysql> select avg(b.price) as avg,b.bookname,b.price,b.state from book as b wher
e b.price<(select avg(price) from book);
+-----------+-----------------+-------+-------+
| avg | bookname | price | state |
+-----------+-----------------+-------+-------+
| 36.600000 | MySQL数据库入门 | 36.00 | 1 |
+-----------+-----------------+-------+-------+
1 row in set (0.02 sec)
mysql> select b.bookname,b.price,b.state from book b where state=(select state f
rom book where bookname='三国演义');
+----------+-------+-------+
| bookname | price | state |
+----------+-------+-------+
| 三国演义 | 62.10 | 2 |
| 红楼梦 | 29.70 | 2 |
| 水浒传 | 66.00 | 2 |
+----------+-------+-------+
3 rows in set (0.00 sec)
mysql> select b.bookname,b.price,b.state from book b where price < any(select p
ice from book where state=1);
+----------+-------+-------+
| bookname | price | state |
+----------+-------+-------+
| 红楼梦 | 29.70 | 2 |
+----------+-------+-------+
1 row in set (0.02 sec)
mysql> alter table book add constraint fk_id foreign key(borrower_id) references
user(id);
Query OK, 7 rows affected (0.30 sec)
Records: 7 Duplicates: 0 Warnings: 0
mysql> show create table book\G;
*************************** 1. row ***************************
Table: book
Create Table: CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`bookname` varchar(20) NOT NULL,
`price` decimal(6,2) NOT NULL,
`upload_time` datetime NOT NULL,
`borrower_id` int(11) DEFAULT NULL,
`borrow_time` datetime DEFAULT NULL,
`state` char(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`bookname`),
UNIQUE KEY `bookname` (`bookname`),
KEY `fk_id` (`borrower_id`),
CONSTRAINT `fk_id` FOREIGN KEY (`borrower_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
ERROR:
No query specified
实训2
- 在数据库chapter05中建两张表
department
did | int(4), | Not null, primary key |
---|---|---|
dname | Varchar(36), |
id | Int(4), | Not null,primary key |
---|---|---|
name | Varchar(36), | |
age | Int(2), | |
did | Int(4), | Not null |
Employee
- 在department中插入数据(1,'网络部'),(2,'媒体部'),(3,'研发部'),(5,'人事部')
- 在employee中插入四条数据(1,'王红',20,1),(2,'李强',22,1),(3,'赵四',20,2),(4,'郝鹃',20,4),
- 使用交叉连接查询部门表和员工表中所有的数据
- 使用内连接查询两个表
- 查询王红所在部门有哪些员工
mysql>
mysql>
mysql> create schema chapter05;
Query OK, 1 row affected (0.00 sec)
mysql> use chapter05;
Database changed
mysql> create table department;
ERROR 1113 (42000): A table must have at least 1 column
mysql> create table department (did int(4) not null primary key,dname varchar(36
));
Query OK, 0 rows affected (0.07 sec)
mysql> desc department;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| did | int(4) | NO | PRI | NULL | |
| dname | varchar(36) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql>
mysql>
mysql> alter table department convert to character set utf8mb4;
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> insert into department values (1,'网络部'),(2,'媒体部'),(3,'研发部'),(5,'
人事部')
-> ;
Query OK, 4 rows affected (0.02 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from department;
+-----+--------+
| did | dname |
+-----+--------+
| 1 | 网络部 |
| 2 | 媒体部 |
| 3 | 研发部 |
| 5 | 人事部 |
+-----+--------+
4 rows in set (0.00 sec)
mysql> create schema employee (id int(4) not null primary key,
-> name varchar(36),
-> age int(2),
-> did int(4) not null);
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near '(id i
nt(4) not null primary key,
name varchar(36),
age int(2),
did int(4) not nu' at line 1
mysql> create table employee (id int(4) not null primary key,
-> name varchar(36),
-> age int(2),
-> did int(4) not null);
Query OK, 0 rows affected (0.04 sec)
mysql> desc employee;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(4) | NO | PRI | NULL | |
| name | varchar(36) | YES | | NULL | |
| age | int(2) | YES | | NULL | |
| did | int(4) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
mysql> insert into employee values (1,'王红',20,1),(2,'李强',22,1),(3,'赵四',20,
2),(4,'郝鹃',20,4);
Query OK, 4 rows affected (0.03 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> select * from employee cross join department on employee;
ERROR 1054 (42S22): Unknown column 'employee' in 'on clause'
mysql> select * from employee cross join department;
+----+------+------+-----+-----+--------+
| id | name | age | did | did | dname |
+----+------+------+-----+-----+--------+
| 1 | 王红 | 20 | 1 | 1 | 网络部 |
| 2 | 李强 | 22 | 1 | 1 | 网络部 |
| 3 | 赵四 | 20 | 2 | 1 | 网络部 |
| 4 | 郝鹃 | 20 | 4 | 1 | 网络部 |
| 1 | 王红 | 20 | 1 | 2 | 媒体部 |
| 2 | 李强 | 22 | 1 | 2 | 媒体部 |
| 3 | 赵四 | 20 | 2 | 2 | 媒体部 |
| 4 | 郝鹃 | 20 | 4 | 2 | 媒体部 |
| 1 | 王红 | 20 | 1 | 3 | 研发部 |
| 2 | 李强 | 22 | 1 | 3 | 研发部 |
| 3 | 赵四 | 20 | 2 | 3 | 研发部 |
| 4 | 郝鹃 | 20 | 4 | 3 | 研发部 |
| 1 | 王红 | 20 | 1 | 5 | 人事部 |
| 2 | 李强 | 22 | 1 | 5 | 人事部 |
| 3 | 赵四 | 20 | 2 | 5 | 人事部 |
| 4 | 郝鹃 | 20 | 4 | 5 | 人事部 |
+----+------+------+-----+-----+--------+
16 rows in set (0.00 sec)
mysql> select * from employee inner join department on employee.did = department
.did;
+----+------+------+-----+-----+--------+
| id | name | age | did | did | dname |
+----+------+------+-----+-----+--------+
| 1 | 王红 | 20 | 1 | 1 | 网络部 |
| 2 | 李强 | 22 | 1 | 1 | 网络部 |
| 3 | 赵四 | 20 | 2 | 2 | 媒体部 |
+----+------+------+-----+-----+--------+
3 rows in set (0.00 sec)
mysql> select * from employee where did=(select * employee where name='王红');
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'emplo
yee where name='王红')' at line 1
mysql> select * from employee where did=(select * from employee where name='王红
');
ERROR 1241 (21000): Operand should contain 1 column(s)
mysql> select * from employee where did=(select did from employee where name='王
红');
+----+------+------+-----+
| id | name | age | did |
+----+------+------+-----+
| 1 | 王红 | 20 | 1 |
| 2 | 李强 | 22 | 1 |
+----+------+------+-----+
2 rows in set (0.00 sec)
实训3
1带in关键字的子查询
例1,查询存在年龄为20岁的员工的部门
例2,查询不存在年龄为20岁的员工的部门
2带exists关键字的子查询
例,查询employee表中是否存在年龄大于21岁的员工,如果存在,则查询department表中的所有记录。
3带any关键字的子查询
例,查询department表中did大于employee表中任一个did的部门
4带all关键字
例,查询department表中did大于employee表中所有did的部门
5带比较运算符的
例,使用带比较运算符的子查询,查询赵四是哪个部门的员工
mysql> select * from department inner join employee on employee.age=20;
+-----+--------+----+------+------+-----+
| did | dname | id | name | age | did |
+-----+--------+----+------+------+-----+
| 1 | 网络部 | 1 | 王红 | 20 | 1 |
| 2 | 媒体部 | 1 | 王红 | 20 | 1 |
| 3 | 研发部 | 1 | 王红 | 20 | 1 |
| 5 | 人事部 | 1 | 王红 | 20 | 1 |
| 1 | 网络部 | 3 | 赵四 | 20 | 2 |
| 2 | 媒体部 | 3 | 赵四 | 20 | 2 |
| 3 | 研发部 | 3 | 赵四 | 20 | 2 |
| 5 | 人事部 | 3 | 赵四 | 20 | 2 |
| 1 | 网络部 | 4 | 郝鹃 | 20 | 4 |
| 2 | 媒体部 | 4 | 郝鹃 | 20 | 4 |
| 3 | 研发部 | 4 | 郝鹃 | 20 | 4 |
| 5 | 人事部 | 4 | 郝鹃 | 20 | 4 |
+-----+--------+----+------+------+-----+
12 rows in set (0.00 sec)
mysql> select * from department inner join employee on employee.age=20;
+-----+--------+----+------+------+-----+
| did | dname | id | name | age | did |
+-----+--------+----+------+------+-----+
| 1 | 网络部 | 1 | 王红 | 20 | 1 |
| 2 | 媒体部 | 1 | 王红 | 20 | 1 |
| 3 | 研发部 | 1 | 王红 | 20 | 1 |
| 5 | 人事部 | 1 | 王红 | 20 | 1 |
| 1 | 网络部 | 3 | 赵四 | 20 | 2 |
| 2 | 媒体部 | 3 | 赵四 | 20 | 2 |
| 3 | 研发部 | 3 | 赵四 | 20 | 2 |
| 5 | 人事部 | 3 | 赵四 | 20 | 2 |
| 1 | 网络部 | 4 | 郝鹃 | 20 | 4 |
| 2 | 媒体部 | 4 | 郝鹃 | 20 | 4 |
| 3 | 研发部 | 4 | 郝鹃 | 20 | 4 |
| 5 | 人事部 | 4 | 郝鹃 | 20 | 4 |
+-----+--------+----+------+------+-----+
12 rows in set (0.00 sec)
mysql> select dname from department inner join employee on employee.age=20 and e
mployee.did=department.did;
+--------+
| dname |
+--------+
| 网络部 |
| 媒体部 |
+--------+
2 rows in set (0.02 sec)
mysql> select * from department where did in (select did from employee where age
=20 );
+-----+--------+
| did | dname |
+-----+--------+
| 1 | 网络部 |
| 2 | 媒体部 |
+-----+--------+
2 rows in set (0.02 sec)
mysql> select * from department where did not in (select did from employee where
age=20 );
+-----+--------+
| did | dname |
+-----+--------+
| 3 | 研发部 |
| 5 | 人事部 |
+-----+--------+
2 rows in set (0.01 sec)
mysql> select * from department where age exists (select * from employee where a
ge>21 );
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'exist
s (select * from employee where age>21 )' at line 1
mysql> select * from department where exists (select * from employee where age>
21 );
+-----+--------+
| did | dname |
+-----+--------+
| 1 | 网络部 |
| 2 | 媒体部 |
| 3 | 研发部 |
| 5 | 人事部 |
+-----+--------+
4 rows in set (0.00 sec)
mysql> select * from department where not exists (select * from employee where
age>21 );
Empty set (0.00 sec)
mysql> select * from department where did > any (select did from employee );
+-----+--------+
| did | dname |
+-----+--------+
| 2 | 媒体部 |
| 3 | 研发部 |
| 5 | 人事部 |
+-----+--------+
3 rows in set (0.00 sec)
mysql> select * from department where did > all (select did from employee );
+-----+--------+
| did | dname |
+-----+--------+
| 5 | 人事部 |
+-----+--------+
1 row in set (0.00 sec)
mysql> select * from department where did = (select did from employee where nam
e = '赵四' );
+-----+--------+
| did | dname |
+-----+--------+
| 2 | 媒体部 |
+-----+--------+
1 row in set (0.00 sec)
第5章 多表操作.pptx
https://www.alipan.com/s/ncMMHnK36jr