一、前言
连接分为内连接(INNER JOIN)、左连接(LEFT JOIN)、右连接(RIGHT JOIN)、全连接(UNION)。它们之间的关系,如下图所示。
接下来,我们将使用销售数据来演示MYSQL中的各种连接查找。
销售订单的建表语句如下:
- 商品表(Product Table):用于存储商品的基本信息,如:商品编号(ProductID)、商品名称(ProductName)、商品价格(ProductPrice)、商品类别(Category)等。每一行代表一个唯一的商品。
- 销售记录表(Sales Record Table): 用于记录每笔销售的详细信息,包括销售日期、销售记录编号(SalesRecordID)、商品编号(ProductID,关联到商品表中的商品编号)、
销售日期(SalesDate)、销售数量(Quantity)、销售额(SalesAmount)、客户姓名(CustomerName)、客户联系方式(CustomerContact)、付款方式(PaymentMethod)。
-- 创建商品表
CREATE TABLE Product (
ProductID INT PRIMARY KEY,
ProductName VARCHAR(255),
Price DECIMAL(10, 2),
Category VARCHAR(50)
);
--INT PRIMARY KEY 表示该列是表的主键,并且它的数据类型是整数(Integer)
--DECIMAL(10, 2) 表示该列可以存储最多 10 个数字,其中有 2 位是小数
-- 创建销售记录表
CREATE TABLE SalesRecord (
SalesRecordID INT PRIMARY KEY,
ProductID INT,
SalesDate DATE,
Quantity INT,
SalesAmount DECIMAL(10, 2),
CustomerName VARCHAR(100),
CustomerContact VARCHAR(100),
PaymentMethod VARCHAR(50),
FOREIGN KEY (ProductID) REFERENCES Product(ProductID)
);
--FOREIGN KEY (ProductID) 表示该列是一个外键,即该列的值必须在当前表中存在,并且可以与另一个表的列建立关联。
-- 向商品表中插入数据
INSERT INTO Product (ProductID, ProductName, Price, Category)
VALUES
(1, '商品A', 10.99, '类别1'),
(2, '商品B', 20.50, '类别2'),
(3, '商品C', 15.75, '类别1');
-- 向销售记录表中插入数据
INSERT INTO SalesRecord (SalesRecordID, ProductID, SalesDate, Quantity, SalesAmount, CustomerName, CustomerContact, PaymentMethod)
VALUES
(1, 1, '2024-03-01', 3, 32.97, '张三', '123456789', '支付宝'),
(2, 2, '2024-03-02', 2, 41.00, '李四', '987654321', '微信'),
(3, 1, '2024-03-03', 1, 10.99, '王五', '555555555', '现金');
二、内连接(INNER JOIN)
内连接(INNER JOIN)是 SQL 中用于合并两个或多个表中匹配行的一种方法。内连接只返回匹配关联条件的行,如果在一个表中没有与另一个表中的行匹配的行,则不会包括在结果中。
下面是一个内连接的例子:获取每个销售记录的产品信息。
SELECT
Product.ProductID,
Product.ProductName,
SalesRecord.SalesDate,
SalesRecord.Quantity,
SalesRecord.SalesAmount
FROM Product
INNER JOIN SalesRecord ON Product.ProductID = SalesRecord.ProductID;
执行结果:
三、左连接 (LEFT JOIN)
左连接(LEFT JOIN)返回左表中的所有行,以及与左表中的行匹配的右表中的行。如果在右表中没有匹配的行,则将在结果集中显示 NULL 值。
SELECT
Product.ProductID,
Product.ProductName,
SalesRecord.SalesDate,
SalesRecord.Quantity,
SalesRecord.SalesAmount
FROM Product
LEFT JOIN SalesRecord ON Product.ProductID = SalesRecord.ProductID;
执行结果
四、右连接 (RIGHT JOIN)
右连接(RIGHT JOIN)和左连接类似,但是它返回右表中的所有行,以及与右表中的行匹配的左表中的行。如果在左表中没有匹配的行,则将在结果集中显示 NULL 值。
SELECT Product.ProductID, Product.ProductName, SalesRecord.SalesDate, SalesRecord.Quantity, SalesRecord.SalesAmount
FROM Product
RIGHT JOIN SalesRecord ON Product.ProductID = SalesRecord.ProductID;
执行结果:
五、全连接 (UNION)
全连接(FULL JOIN)将返回左表和右表中的所有行,并将它们组合在一起。如果某个行在左表中没有匹配的行,则该行的右表列将显示为 NULL。如果某个行在右表中没有匹配的行,则该行的左表列将显示为 NULL。
SELECT Product.ProductID, Product.ProductName, SalesRecord.SalesDate, SalesRecord.Quantity, SalesRecord.SalesAmount
FROM Product
LEFT JOIN SalesRecord ON Product.ProductID = SalesRecord.ProductID
UNION
SELECT Product.ProductID, Product.ProductName, SalesRecord.SalesDate, SalesRecord.Quantity, SalesRecord.SalesAmount
FROM Product
RIGHT JOIN SalesRecord ON Product.ProductID = SalesRecord.ProductID;
执行结果: