183. 从不订购的客户
题目描述
Customers 表:
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | name | varchar | +-------------+---------+ 在 SQL 中,id 是该表的主键。 该表的每一行都表示客户的 ID 和名称。
Orders 表:
+-------------+------+ | Column Name | Type | +-------------+------+ | id | int | | customerId | int | +-------------+------+ 在 SQL 中,id 是该表的主键。 customerId 是 Customers 表中 ID 的外键( Pandas 中的连接键)。 该表的每一行都表示订单的 ID 和订购该订单的客户的 ID。
找出所有从不点任何东西的顾客。
以 任意顺序 返回结果表。
结果格式如下所示。
示例 1:
输入: Customers table: +----+-------+ | id | name | +----+-------+ | 1 | Joe | | 2 | Henry | | 3 | Sam | | 4 | Max | +----+-------+ Orders table: +----+------------+ | id | customerId | +----+------------+ | 1 | 3 | | 2 | 1 | +----+------------+ 输出: +-----------+ | Customers | +-----------+ | Henry | | Max | +-----------+
解法
方法一:NOT IN
思考
没有下过单的客户,即 \(\textit{id}\) 不在订单表的 \(\textit{customerId}\) 集合里。\(\textit{NOT IN}\) 直接表达这个集合差;注意订单表为空时部分引擎对 \(\textit{NOT IN}\) 的空集语义。
列举所有已存在订单的客户 ID,使用 NOT IN 找到不存在其中的客户。
1 2 3 4 5 6 7 8 9 10 11 | |
1 2 3 4 5 6 7 8 | |
方法二:LEFT JOIN
思考
方法一在子查询很大时不够友好。左连接订单表后保留 \(\textit{customerId}\) 为空的行,避免 \(\textit{NOT IN}\) 对 \(\textit{NULL}\) 的陷阱,也便于走连接计划。
使用 LEFT JOIN 连接表格,返回 CustomerId 为 NULL 的数据。
1 2 3 4 5 6 | |