sql-right-joins
SQL - RIGHT JOIN
Section titled “SQL - RIGHT JOIN”A RIGHT JOIN(或 RIGHT OUTER JOIN)是一种外连接,它返回右表(table2)中的所有行,以及左表(table1)中匹配的行。如果右表中的某一行在左表中没有匹配的行,则结果中左表的所有列将包含 NULL 值。
SQL RIGHT JOIN
Section titled “SQL RIGHT JOIN”从视觉上,你可以将 RIGHT JOIN 理解为获取右表中的每一行,然后尝试根据连接条件在左表中查找匹配项。
要点:右表中的所有行都将包含在结果中,无论它们在左表中是否有匹配项。
SELECT table1.column_name, table2.column_nameFROM table1RIGHT JOIN table2 ON table1.common_field = table2.common_field;注意:RIGHT JOIN 和 RIGHT OUTER JOIN 在所有主要的 SQL 方言中功能相同。
让我们考虑两个表:CUSTOMERS 和 ORDERS。
CREATE TABLE CUSTOMERS ( ID INT PRIMARY KEY, NAME VARCHAR(100) NOT NULL, AGE INT NOT NULL);
INSERT INTO CUSTOMERS (ID, NAME, AGE) VALUES(1, 'Ramesh', 32),(2, 'Khilan', 25),(3, 'Kaushik', 23),(4, 'Chaitali', 25);CREATE TABLE ORDERS ( OID INT PRIMARY KEY, ORDER_DATE TIMESTAMP NOT NULL, CUSTOMER_ID INT, AMOUNT DECIMAL(10, 2));
INSERT INTO ORDERS (OID, ORDER_DATE, CUSTOMER_ID, AMOUNT) VALUES(101, '2023-11-20 10:30:00', 2, 1560.00),(102, '2023-10-08 14:00:00', 3, 3000.00),(103, '2023-05-20 18:45:00', 4, 2060.00),(104, '2023-12-01 09:00:00', 99, 500.00); -- 来自一个不存在客户的订单请注意,ORDERS 表中有一个 CUSTOMER_ID 为 99 的订单,该客户在 CUSTOMERS 表中不存在。让我们执行一个 RIGHT JOIN 来列出所有订单及其下单客户。
SELECT c.ID, c.NAME, o.OID, o.AMOUNTFROM CUSTOMERS cRIGHT JOIN ORDERS o ON c.ID = o.CUSTOMER_ID;| ID | NAME | OID | AMOUNT |
|---|---|---|---|
| 2 | Khilan | 101 | 1560.00 |
| 3 | Kaushik | 102 | 3000.00 |
| 4 | Chaitali | 103 | 2060.00 |
| NULL | NULL | 104 | 500.00 |
结果包含了所有四个订单。对于订单 ID 104,客户列(ID、NAME)为 NULL,因为 CUSTOMER_ID 99 在 CUSTOMERS 表中没有匹配项。
专业提示:为了可读性,优先使用 LEFT JOIN
Section titled “专业提示:为了可读性,优先使用 LEFT JOIN”虽然 RIGHT JOIN 在功能上是有效的,但许多开发人员发现 LEFT JOIN 更直观、更易读,因为我们倾向于从左到右思考。任何 RIGHT JOIN 都可以通过简单地交换表来重写为 LEFT JOIN。
上一个 RIGHT JOIN 等效于以下 LEFT JOIN:
-- 此 LEFT JOIN 会产生完全相同的结果,并且通常更清晰。SELECT c.ID, c.NAME, o.OID, o.AMOUNTFROM ORDERS oLEFT JOIN CUSTOMERS c ON o.CUSTOMER_ID = c.ID;你可以将多个 JOIN 操作链式连接在一起。这些 JOIN 通常从左到右进行评估。让我们添加一个 SALESPERSON 表并将其链接到 ORDERS。
-- 向 ORDERS 表添加 SALESPERSON_ID 列并创建 SALESPERSON 表ALTER TABLE ORDERS ADD COLUMN SALESPERSON_ID INT;UPDATE ORDERS SET SALESPERSON_ID = 1 WHERE OID IN (101, 102);UPDATE ORDERS SET SALESPERSON_ID = 2 WHERE OID IN (103, 104);
CREATE TABLE SALESPERSON ( SID INT PRIMARY KEY, SNAME VARCHAR(100));INSERT INTO SALESPERSON (SID, SNAME) VALUES (1, 'Sarika'), (2, 'Vivek');-- 让我们查找所有销售人员以及他们关联的订单SELECT s.SNAME AS SalespersonName, o.OID AS OrderID, c.NAME AS CustomerNameFROM CUSTOMERS cRIGHT JOIN ORDERS o ON c.ID = o.CUSTOMER_IDRIGHT JOIN SALESPERSON s ON o.SALESPERSON_ID = s.SID;此查询以 SALESPERSON 作为基表(最终 JOIN 中的最右侧表),确保所有销售人员都被列出。
| SalespersonName | OrderID | CustomerName |
|---|---|---|
| Sarika | 101 | Khilan |
| Sarika | 102 | Kaushik |
| Vivek | 103 | Chaitali |
| Vivek | 104 | NULL |
带 WHERE 子句的 RIGHT JOIN
Section titled “带 WHERE 子句的 RIGHT JOIN”WHERE 子句用于在执行 JOIN 之后 过滤结果。这允许你对连接后的结果集应用条件。
SELECT c.ID, c.NAME, o.AMOUNTFROM CUSTOMERS cRIGHT JOIN ORDERS o ON c.ID = o.CUSTOMER_IDWHERE o.AMOUNT > 2000.00;这将只返回金额大于 2000.00 的订单,同时仍保持 RIGHT JOIN 逻辑。
| ID | NAME | AMOUNT |
|---|---|---|
| 3 | Kaushik | 3000.00 |
| 4 | Chaitali | 2060.00 |