PostgreSQL 连接(JOIN)详解
在 PostgreSQL 中,JOIN 用于将两个或多个表的数据关联起来,根据特定的条件组合数据。
1. JOIN 的类型
PostgreSQL 提供了多种 JOIN 类型:
INNER JOIN(内连接)LEFT JOIN(左连接)RIGHT JOIN(右连接)FULL JOIN(全连接)CROSS JOIN(交叉连接)SELF JOIN(自连接)
2. INNER JOIN(内连接)
INNER JOIN 仅返回两个表中 匹配 的数据行,不匹配的数据不会出现在结果集中。
2.1 语法
SELECT A.*, B.*
FROM table_A A
INNER JOIN table_B B
ON A.common_column = B.common_column;
2.2 示例
假设有两个表:
CREATE TABLE customers (
id SERIAL PRIMARY KEY,
name VARCHAR(100)
);
CREATE TABLE orders (
id SERIAL PRIMARY KEY,
customer_id INT,
product VARCHAR(100),
FOREIGN KEY (customer_id) REFERENCES customers(id)
);
插入测试数据:
INSERT INTO customers (id, name) VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Charlie');
INSERT INTO orders (id, customer_id, product) VALUES (1, 1, 'Laptop'), (2, 2, 'Phone');
执行 INNER JOIN:
SELECT customers.name, orders.product
FROM customers
INNER JOIN orders
ON customers.id = orders.customer_id;
结果:
| name | product |
|---|---|
| Alice | Laptop |
| Bob | Phone |
Charlie 没有订单,因此不会出现在结果中。
3. LEFT JOIN(左连接)
LEFT JOIN 返回左表的所有记录,即使右表中没有匹配的数据。
3.1 语法
SELECT A.*, B.*
FROM table_A A
LEFT JOIN table_B B
ON A.common_column = B.common_column;
3.2 示例
SELECT customers.name, orders.product
FROM customers
LEFT JOIN orders
ON customers.id = orders.customer_id;
结果:
| name | product |
|---|---|
| Alice | Laptop |
| Bob | Phone |
| Charlie | NULL |
即使 Charlie 没有订单,他仍然出现在结果中,product 列显示 NULL。
4. RIGHT JOIN(右连接)
RIGHT JOIN 返回右表的所有数据,即使左表中没有匹配的记录。
4.1 语法
SELECT A.*, B.*
FROM table_A A
RIGHT JOIN table_B B
ON A.common_column = B.common_column;
4.2 示例
SELECT customers.name, orders.product
FROM customers
RIGHT JOIN orders
ON customers.id = orders.customer_id;
由于 orders 表中所有数据都匹配 customers,结果与 INNER JOIN 相同。
如果 orders 表有数据但 customers 没有匹配的 id,也会返回数据,但 customers.name 会显示 NULL。
5. FULL JOIN(全连接)
FULL JOIN 返回左表和右表的所有数据,若没有匹配的部分,则返回 NULL。
5.1 语法
SELECT A.*, B.*
FROM table_A A
FULL JOIN table_B B
ON A.common_column = B.common_column;
5.2 示例
SELECT customers.name, orders.product
FROM customers
FULL JOIN orders
ON customers.id = orders.customer_id;
结果:
| name | product |
|---|---|
| Alice | Laptop |
| Bob | Phone |
| Charlie | NULL |
| NULL | Tablet |
如果 orders 表中有订单属于一个 customer_id 但 customers 表中不存在该 id,则 name 会是 NULL。
6. CROSS JOIN(交叉连接)
CROSS JOIN 生成笛卡尔积,返回所有可能的组合,不需要 ON 条件。
6.1 语法
SELECT A.*, B.*
FROM table_A A
CROSS JOIN table_B B;
6.2 示例
SELECT customers.name, orders.product
FROM customers
CROSS JOIN orders;
如果 customers 表有 3 条记录,orders 表有 2 条记录,则结果将有 3 × 2 = 6 行。
7. SELF JOIN(自连接)
SELF JOIN 是同一个表的连接,用于查找相同表中的相关数据。
7.1 语法
SELECT A.*, B.*
FROM table_A A
INNER JOIN table_A B
ON A.column = B.column;
7.2 示例
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
manager_id INT
);
插入数据:
INSERT INTO employees (id, name, manager_id)
VALUES (1, 'Alice', NULL),
(2, 'Bob', 1),
(3, 'Charlie', 1),
(4, 'David', 2);
查询每个员工的上级:
SELECT e1.name AS employee, e2.name AS manager
FROM employees e1
LEFT JOIN employees e2
ON e1.manager_id = e2.id;
结果:
| employee | manager |
|---|---|
| Alice | NULL |
| Bob | Alice |
| Charlie | Alice |
| David | Bob |
8. 使用 USING 代替 ON
如果连接的列名相同,可以使用 USING 关键字简化 JOIN 语句:
SELECT customers.name, orders.product
FROM customers
INNER JOIN orders USING (id);
9. 总结
| 连接类型 | 作用 |
|---|---|
INNER JOIN | 只返回匹配的数据 |
LEFT JOIN | 返回左表所有数据,右表不匹配返回 NULL |
RIGHT JOIN | 返回右表所有数据,左表不匹配返回 NULL |
FULL JOIN | 返回两表所有数据,不匹配的部分为 NULL |
CROSS JOIN | 生成两表的笛卡尔积 |
SELF JOIN | 在同一个表内查找相关数据 |
更多详细内容请关注其他相关文章!