LEFT JOIN 条件放在ON后面还是WHERE后面
通常是放在ON后面,因为LEFT JOIN的设计是返回左表的所有记录,即使右表没有记录。
如果条件放在WHERE后面,会过滤结果集,可能会改变查询的结果,偏离期望。
例子
CUSTOMER
| ID | NAME |
|---|---|
| 1 | A |
| 2 | B |
| 3 | C |
ORDERS
| ID | CUSTOMER_ID | AMOUNT |
|---|---|---|
| 101 | 1 | 10 |
| 102 | 1 | 20 |
| 103 | 2 | 30 |
SELECT c.ID as CUSTOMER_ID, c.NAME, o.ID as ORDER_ID, o.AMOUNT
FROM CUSTOMER c
LEFT JOIN ORDERS o
ON c.ID = o.CUSTOMER_ID AND o.AMOUNT > 10
查询结果:
| CUSTOMER_ID | NAME | ORDER_ID | AMOUNT |
|---|---|---|---|
| 1 | A | 102 | 20 |
| 2 | B | 103 | 30 |
| 3 | C | null | null |
SELECT c.ID, c.NAME, o.ID, o.AMOUNT
FROM CUSTOMER c
LEFT JOIN ORDERS o
ON c.ID = o.CUSTOMER_ID
查询结果:
| CUSTOMER_ID | NAME | ORDER_ID | AMOUNT |
|---|---|---|---|
| 1 | A | 101 | 10 |
| 1 | A | 102 | 20 |
| 2 | B | 103 | 30 |
| 3 | C | null | null |
SELECT c.ID, c.NAME, o.ID, o.AMOUNT
FROM CUSTOMER c
LEFT JOIN ORDERS o
ON c.ID = o.CUSTOMER_ID WHERE o.AMOUNT > 10
查询结果:
| CUSTOMER_ID | NAME | ORDER_ID | AMOUNT |
|---|---|---|---|
| 1 | A | 102 | 20 |
| 2 | B | 103 | 30 |
多个LEFT JOIN
需要从多个表中获取相关数据时,可以使用多个LEFT JOIN。
SELECT 列名 FROM 表1 LEFT JOIN 表2 ON 表1.列 = 表2.列 LEFT JOIN 表3 ON 表1.列 = 表3.列 或 表2.列 = 表3.列 ...
假设有三个表:
customers(客户表)orders(订单表)payments(付款表)
需要哦返回所有客户的订单和付款数据,包括没有订单或者没有付款的客户。
SELECT
c.customer_id,
c.customer_name,
o.order_id,
o.order_date,
p.amount,
p.payment_date
FROM
customers c
LEFT JOIN
orders o ON c.customer_id = o.customer_id
LEFT JOIN
payments p ON o.order_id = p.order_id
注意:
1. 执行顺序:SQL会按照FROM子句中表的顺序依次执行LEFT JOIN
2. 性能影响:每个LEFT JOIN都会增加查询的复杂度,可能影响性能
3. NULL值处理:当右表没有匹配记录时,结果中该表的所有列将为NULL
4. 连接条件:确保连接条件正确,避免笛卡尔积
替代方案:
如果只需要左表的记录,而不需要右表的部分数据,可以考虑使用子查询或EXISTS子句来提高性能。
-- 使用EXISTS替代LEFT JOIN的示例
SELECT c.*
FROM customers c
WHERE EXISTS (
SELECT 1 FROM orders o WHERE o.customer_id = c.customer_id
)