PostgreSQL 连接(JOIN)详解
                           
天天向上
发布: 2025-03-12 23:32:06

原创
824 人浏览过

在 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;

结果

nameproduct
AliceLaptop
BobPhone

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;

结果

nameproduct
AliceLaptop
BobPhone
CharlieNULL

即使 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;

结果

nameproduct
AliceLaptop
BobPhone
CharlieNULL
NULLTablet

如果 orders 表中有订单属于一个 customer_idcustomers 表中不存在该 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;

结果

employeemanager
AliceNULL
BobAlice
CharlieAlice
DavidBob

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在同一个表内查找相关数据

更多详细内容请关注其他相关文章!

发表回复 0

Your email address will not be published. Required fields are marked *