域名 AXUM.RS 将于2025年10月到期。我们无意再对其进行续费,我们希望你能够接续这个域名,让更多 AXUM 开发者继续受益。
  • 方案1️⃣AXUM.RS 域名 = 3000
  • 方案2️⃣方案1️⃣ + 本站所有专题原始 Markdown 文档 = 5000
  • 方案3️⃣方案2️⃣ + 本站原始数据库 = 5500
如果你有意接续这份 AXUM 情怀,请与我们取得联系。
说明:
  1. 如果有人购买 AXUM.RS 域名(方案1️⃣),或者该域名到期,本站将启用新的免费域名继续提供服务。
  2. 如果有人购买了 AXUM.RS 域名,且同时购买了内容和/或数据库(方案2️⃣/方案3️⃣),本站将关闭。届时我们或许会以另一种方式与你再相遇。

连接

开始之前,先创建两张表并插入一些数据:

CREATE TABLE basket_a (
    a INT PRIMARY KEY,
    fruit_a VARCHAR (100) NOT NULL
);

CREATE TABLE basket_b (
    b INT PRIMARY KEY,
    fruit_b VARCHAR (100) NOT NULL
);

INSERT INTO basket_a (a, fruit_a)
VALUES
    (1, 'Apple'),
    (2, 'Orange'),
    (3, 'Banana'),
    (4, 'Cucumber');

INSERT INTO basket_b (b, fruit_b)
VALUES
    (1, 'Orange'),
    (2, 'Apple'),
    (3, 'Watermelon'),
    (4, 'Pear');

内连接

SELECT
    a,
    fruit_a,
    b,
    fruit_b
FROM
    basket_a
INNER JOIN basket_b
    ON fruit_a = fruit_b;
  • 使用 INNER JOIN 进行连接,使用 ON 指定连接条件
  • 内连接检查第一个表(basket_a)中每一行,并与第二个表(basket_b)的每一行进行对比:如果指定字段的值相等(由 ON 指定的 fruit_afruit_b),则创建新行,并将该行添加到结果集中。

左外连接

SELECT
    a,
    fruit_a,
    b,
    fruit_b
FROM
    basket_a
LEFT JOIN basket_b 
   ON fruit_a = fruit_b;
  • 使用 LEFT JOIN 进行连接,使用 ON 指定条件
    • LEFT JOIN 左侧的表为“左表”,此例中的 basket_a
    • LEFT JOIN 右侧的表为“右表”,此例中的 basket_b
  • 从左表(basket_a)中选择数据,并将它的 fruit_a字段的值和右表(basket_b)的 fruit_b 字段值进行对比(由 ON 指定):
    • 如果相等,将创建一个包含两张表记录的新行,并将新行添加到结果集中
    • 如果不相等,只创建只包含左表记录,右边记录全部为 NULL 的新行,并将新行添加到结果集中
  • LEFT JOIN 左侧的表为“左表”,此例中的 basket_a
  • LEFT JOIN 右侧的表为“右表”,此例中的 basket_b
  • 如果相等,将创建一个包含两张表记录的新行,并将新行添加到结果集中
  • 如果不相等,只创建只包含左表记录,右边记录全部为 NULL 的新行,并将新行添加到结果集中

LEFT JOINLEFT OUTER JOIN 的简写

LEFT JOINLEFT OUTER JOIN 的简写

右外连接

  • 和左外连接原理相同
  • 只是以右表的记录为准,对右表选择数据,如果左表有相等的记录则包含左表数据;反则则只包含右表数据,左表为 NULL

全外连接

SELECT
    a,
    fruit_a,
    b,
    fruit_b
FROM
    basket_a
FULL OUTER JOIN basket_b 
    ON fruit_a = fruit_b;

交叉连接

  • 没有 ON 指定条件
  • 这是一个非常耗费资源的操作
SELECT 字段列表 FROM t1 CROSS JOIN t1;

-- 等价于
SELECT 字段列表 FROM t1,t2;

-- 使用INNER JOIN模拟:ON的条件始终为真
SELECT 字段列表 FROM t1 INNER JOIN t2 ON 1=1;

自然连接

基于连接表中,相同字段名创建的隐式连接。

SELECT 字段列表 FROM t1 NATURAL [INNER, LEFT, RIGHT] JOIN t2;
SELECT * FROM city NATURAL INNER JOIN country;
  • 预期将隐式使用两个表中的同名字段 country_id 进行连接
  • 实际结果确是空结果,原因是两个表中还有一个同名字段 last_update

自连接

所谓自连接,是指连接两方都是同一张表,常用应用场景是父子分类。

SELECT FROM 字段列表 FROM 表 AS t1 INNER JOIN 表 AS t2 ON t1.字段名1 = t2.字段名2; 

示例:

CREATE TABLE employee (
	employee_id INT PRIMARY KEY,
	first_name VARCHAR (255) NOT NULL,
	last_name VARCHAR (255) NOT NULL,
	manager_id INT,
	FOREIGN KEY (manager_id) 
	REFERENCES employee (employee_id) 
	ON DELETE CASCADE
);
INSERT INTO employee (
	employee_id,
	first_name,
	last_name,
	manager_id
)
VALUES
	(1, 'Windy', 'Hays', NULL),
	(2, 'Ava', 'Christensen', 1),
	(3, 'Hassan', 'Conner', 1),
	(4, 'Anna', 'Reeves', 2),
	(5, 'Sau', 'Norman', 2),
	(6, 'Kelsie', 'Hays', 3),
	(7, 'Tory', 'Goff', 3),
	(8, 'Salley', 'Lester', 3);
	
SELECT
    e.first_name || ' ' || e.last_name AS employee,
    m.first_name || ' ' || m.last_name AS manager
FROM
    employee AS e
INNER JOIN employee AS m ON m.employee_id = e.manager_id
ORDER BY manager;
要查看完整内容,请先登录