订阅更新

从没下过单的客户:反连接的三种写法

SQL 实战 123 题 · 第 8 题 简单 约 2 分钟读完

LeetCode 183 · LEFT JOIN + IS NULL、NOT EXISTS、NOT IN 的陷阱

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

这是反连接。我优先用 NOT EXISTS 或 LEFT JOIN ... WHERE o.Id IS NULL;不太用 NOT IN,因为子查询里只要出现 NULL,NOT IN 的结果就全是未知,会一行都查不出来,这是面试里常被追问的坑。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

有客户表和订单表,订单表记录了下单客户的 ID。找出一次都没下过单的客户姓名。

表结构

  • Customers:Id(主键)、Name
  • Orders:Id(主键)、CustomerId

思路

「在 A 里但不在 B 里」叫反连接。最常用的是 LEFT JOIN 后取右表主键为 NULL 的行;也可以写 NOT EXISTS。NOT IN 也能写,但如果子查询里有 NULL,整个条件会变成未知,一行都查不出来。

参考解法

select  c.Name Customers
from Customers  c left join Orders  o
on c.id = o.CustomerId
where o.id is null

另一种写法:NOT EXISTS,语义最直接,也不受 NULL 影响

SELECT c.Name AS Customers
FROM Customers c
WHERE NOT EXISTS (SELECT 1 FROM Orders o WHERE o.CustomerId = c.Id)

易错点

  • 用 NOT IN (SELECT CustomerId FROM Orders) 时,只要 CustomerId 有一个 NULL,结果就是空集。
  • LEFT JOIN 后判断空要判断右表的非空列(比如主键),不要判断可能本来就为空的列。
刷题进度保存在当前浏览器