1. 什么是表连接?
在SQL中,表连接是指通过共同的字段将两个或多个表联合起来进行查询、更新等操作的过程。
表连接根据共同的字段类型可以分为内连接、左连接、右连接和全连接四种形式。
下面是表连接的四种形式的详细介绍:
1.1 内连接
内连接是指查询两个或多个表中共有的数据。该连接只返回两个表中共有的数据,即只有在两个表中都存在的数据才会被返回。
SELECT
A.order_id,
A.order_date,
B.customer_name
FROM
orders A
INNER JOIN customers B
ON A.customer_id = B.customer_id;
在上面的SQL语句中,orders表和customers表通过customer_id字段进行内连接,只返回既出现在orders表中又出现在customers表中的数据。
1.2 左连接
左连接是指以左表为基础,连接右表中和左表有共同字段的数据,如果右表中没有符合条件的数据,则在查询结果中仍然返回左表中的数据。
SELECT
A.order_id,
A.order_date,
B.customer_name
FROM
orders A
LEFT JOIN customers B
ON A.customer_id = B.customer_id;
在上面的SQL语句中,orders表和customers表通过customer_id字段进行左连接,返回orders表中所有数据以及customers表中与之匹配的数据,如果customers表中没有符合条件的数据,则返回NULL。
1.3 右连接
右连接是指以右表为基础,连接左表中和右表有共同字段的数据,如果左表中没有符合条件的数据,则在查询结果中仍然返回右表中的数据。
SELECT
A.order_id,
A.order_date,
B.customer_name
FROM
orders A
RIGHT JOIN customers B
ON A.customer_id = B.customer_id;
在上面的SQL语句中,orders表和customers表通过customer_id字段进行右连接,返回customers表中所有数据以及orders表中与之匹配的数据,如果orders表中没有符合条件的数据,则返回NULL。
1.4 全连接
全连接是指返回所有左表和右表中的记录,如果左表或右表中没有符合条件的数据,则返回NULL。
SELECT
A.order_id,
A.order_date,
B.customer_name
FROM
orders A
FULL JOIN customers B
ON A.customer_id = B.customer_id;
在上面的SQL语句中,orders表和customers表通过customer_id字段进行全连接,返回orders表和customers表中所有数据,如果某个表中没有符合条件的数据,则返回NULL。
2. 表连接实例
下面以一个图书馆的数据库为例,演示各种表连接的用法。
2.1 数据库表结构
图书馆的数据库包含以下三个表:
books表,包含所有图书的信息,包括isbn、书名、作者、出版社、出版日期和价格等。
readers表,包含所有读者的信息,包括读者编号、姓名、性别、年龄、身份证号码、电话号码和地址等。
borrowed_books表,包含所有借出的图书信息,包括借阅编号、读者编号、isbn、借阅日期、归还日期和借阅状态等。
下面是三个表结构的详细信息:
CREATE TABLE books (
isbn VARCHAR(20) PRIMARY KEY,
book_name VARCHAR(100) NOT NULL,
author VARCHAR(100) NOT NULL,
publisher VARCHAR(100) NOT NULL,
publication_date DATE NOT NULL,
price DECIMAL(6,2) NOT NULL
);
CREATE TABLE readers (
reader_id INT PRIMARY KEY,
reader_name VARCHAR(50) NOT NULL,
gender ENUM('男', '女') NOT NULL,
age INT NOT NULL,
id_card VARCHAR(18) NOT NULL,
phone VARCHAR(11) NOT NULL,
address VARCHAR(200) NOT NULL
);
CREATE TABLE borrowed_books (
borrow_id INT PRIMARY KEY,
reader_id INT NOT NULL,
isbn VARCHAR(20) NOT NULL,
borrow_date DATE NOT NULL,
return_date DATE,
borrow_status ENUM('已借', '已还') NOT NULL,
FOREIGN KEY (reader_id) REFERENCES readers (reader_id),
FOREIGN KEY (isbn) REFERENCES books (isbn)
);
2.2 内连接查询
查询所有已借出的书籍的相关信息(书名、借阅日期、读者姓名):
SELECT
books.book_name,
borrowed_books.borrow_date,
readers.reader_name
FROM
books
INNER JOIN borrowed_books
ON books.isbn = borrowed_books.isbn
INNER JOIN readers
ON borrowed_books.reader_id = readers.reader_id
WHERE
borrowed_books.borrow_status = '已借';
结果示例:
+----------------------------+-------------+-------------------+
| book_name | borrow_date | reader_name |
+----------------------------+-------------+-------------------+
| 创新者的窘境 | 2021-01-03 | 李四 |
| 程序员修炼之道 | 2021-01-04 | 张三 |
| Python数据分析基础(第二版) | 2021-01-05 | 王五 |
+----------------------------+-------------+-------------------+
2.3 左连接查询
查询所有已借出的书籍的相关信息以及未借出的书籍的相关信息(书名、借阅日期、读者姓名):
SELECT
books.book_name,
borrowed_books.borrow_date,
readers.reader_name
FROM
books
LEFT JOIN borrowed_books
ON books.isbn = borrowed_books.isbn
LEFT JOIN readers
ON borrowed_books.reader_id = readers.reader_id
WHERE
borrowed_books.borrow_status = '已借' OR borrowed_books.borrow_id IS NULL;
结果示例:
+----------------------------------+-------------+-------------------+
| book_name | borrow_date | reader_name |
+----------------------------------+-------------+-------------------+
| 创新者的窘境 | 2021-01-03 | 李四 |
| 程序员修炼之道 | 2021-01-04 | 张三 |
| Python数据分析基础(第二版) | 2021-01-05 | 王五 |
| 从0开始学数据结构与算法(C语言版) | NULL | NULL |
| SQL基础教程 | NULL | NULL |
| TensorFlow官方文档 | NULL | NULL |
+----------------------------------+-------------+-------------------+
2.4 右连接查询
查询所有读者的相关信息以及已经借阅的书籍的相关信息(读者姓名、书名、借阅日期):
SELECT
books.book_name,
borrowed_books.borrow_date,
readers.reader_name
FROM
readers
RIGHT JOIN borrowed_books
ON readers.reader_id = borrowed_books.reader_id
RIGHT JOIN books
ON borrowed_books.isbn = books.isbn
WHERE
borrowed_books.borrow_status = '已借' OR borrowed_books.borrow_id IS NULL;
结果示例:
+----------------------------------+-------------+-------------------+
| book_name | borrow_date | reader_name |
+----------------------------------+-------------+-------------------+
| 程序员修炼之道 | 2021-01-04 | 张三 |
| 创新者的窘境 | 2021-01-03 | 李四 |
| Python数据分析基础(第二版) | 2021-01-05 | 王五 |
| 从0开始学数据结构与算法(C语言版) | NULL | NULL |
| SQL基础教程 | NULL | NULL |
| TensorFlow官方文档 | NULL | NULL |
+----------------------------------+-------------+-------------------+
2.5 全连接查询
查询所有读者和借阅信息以及所有书籍的相关信息,如果读者没有借阅图书或书籍没有借阅记录,则返回NULL:
SELECT
books.book_name,
borrowed_books.borrow_date,
readers.reader_name
FROM
readers
FULL JOIN borrowed_books
ON readers.reader_id = borrowed_books.reader_id
FULL JOIN books
ON borrowed_books.isbn = books.isbn;
结果示例:
+----------------------------------+-------------+-------------------+
| book_name | borrow_date | reader_name |
+----------------------------------+-------------+-------------------+
| 程序员修炼之道 | 2021-01-04 | 张三 |
| 创新者的窘境 | 2021-01-03 | 李四 |
| Python数据分析基础(第二版) | 2021-01-05 | 王五 |
| 从0开始学数据结构与算法(C语言版) | NULL | NULL |
| SQL基础教程 | NULL | NULL |
| TensorFlow官方文档 | NULL | NULL |
| NULL | 2021-01-03 | 李四 |
| NULL | 2021-01-04 | 张三 |
| NULL | 2021-01-05 | 王五 |
+----------------------------------+-------------+-------------------+
3. 总结
表连接是SQL中非常重要的概念,通过不同的连接方式,可以将多个表中的数据联合起来进行查询、更新等操作。
在实际的应用中,要根据实际的需求选择不同的连接方式,以达到最佳的查询效果。