183. 从不订购的客户
183. 从不订购的客户
题目
Table: Customers
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | name | varchar | +-------------+---------+
id is the primary key (column with unique values) for this table.
Each row of this table indicates the ID and name of a customer.
Table: Orders
+-------------+------+ | Column Name | Type | +-------------+------+ | id | int | | customerId | int | +-------------+------+
id is the primary key (column with unique values) for this table.
customerId is a foreign key (reference columns) of the ID from the Customers table.
Each row of this table indicates the ID of an order and the ID of the customer who ordered it.
Write a solution to find all customers who never order anything.
Return the result table in any order.
The result format is in the following example.
Example 1:
Input:
Customers table:
+----+-------+ | id | name | +----+-------+ | 1 | Joe | | 2 | Henry | | 3 | Sam | | 4 | Max | +----+-------+
Orders table:
+----+------------+ | id | customerId | +----+------------+ | 1 | 3 | | 2 | 1 | +----+------------+
Output:
+-----------+ | Customers | +-----------+ | Henry | | Max | +-----------+
题目大意
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 | +-----------+
解题思路
MySQL
返回字段:
SELECT
指定要返回的字段:name
(客户名称),重命名为Customers
。FROM Customers
表作为数据来源。筛选条件:
- 使用
LEFT JOIN
将Customers
表与Orders
表连接,关联条件是Customers.id = Orders.customerId
。 - 筛选出未下单的客户,即
Orders.customerId
为NULL
的记录。 - 使用
WHERE o.customerId IS NULL
筛选条件。
- 使用
复杂度分析
- 时间复杂度:
O(n + m)
,其中n
是Customers
表的记录数,m
是Orders
表的记录数。 - 空间复杂度:
O(n)
,返回的结果占用的空间与未下单的客户数成正比。
Pandas
加载数据:
将Customers
和Orders
数据加载到 Pandas 的两个DataFrame
中。左连接:
使用merge
模拟 SQL 的LEFT JOIN
,Customers
为左表,Orders
为右表,关联条件是Customers.id = Orders.customerId
。筛选条件:
筛选出customerId
为NaN
的记录,即未下过订单的客户。选择列:
保留筛选后的name
列,并重命名为Customers
,作为最终结果。
代码
SELECT c.name as Customers
FROM Customers c
LEFT JOIN Orders o
ON c.id = o.customerId
WHERE o.customerId IS NULL
import pandas as pd
def customers_without_orders(customers: pd.DataFrame, orders: pd.DataFrame) -> pd.DataFrame:
# LEFT JOIN 模拟
merged = pd.merge(customers, orders, left_on='id', right_on='customerId', how='left')
# 筛选未下订单的客户
return merged[merged['customerId'].isna()][['name']].rename(columns={'name': 'Customers'})