【简单】力扣算法题解析LeetCode183:从不订购的客户

关注底部名片达文汐,即可获得本题完整源码

题目链接:LeetCode183:从不订购的客户


解题思路

要找出所有从未下过订单的客户,核心思路是筛选出在 Customers 表中存在但在 Orders 表中无关联记录的客户。实现方式有两种高效方法:

  1. LEFT JOIN + IS NULL

    • Customers 表左连接 Orders 表,连接条件为 Customers.id = Orders.customerId
    • 若某个客户无订单,则连接后 Orders.idNULL
    • 直接通过 WHERE Orders.id IS NULL 过滤出目标客户。
  2. NOT EXISTS 子查询

    • 对于 Customers 表中的每个客户,检查是否存在关联的订单记录。
    • 若不存在关联订单,则选择该客户。

效率对比

  • LEFT JOIN 在大多数数据库(如 MySQL)中效率更高,因它只需单次遍历连接表并利用索引。
  • NOT EXISTS 在逻辑上清晰,但可能因子查询导致额外扫描。
  • 推荐使用 LEFT JOIN 以最小化执行时间和内存消耗。

索引优化

  • 确保 Orders.customerId 有索引(外键通常自动索引)。
  • Customers.id 作为主键已有索引,可加速连接。

代码实现(MySQL版)

SELECT 
    c.name AS Customers   -- 选择客户姓名,结果列名为 Customers
FROM 
    Customers c           -- 主表:客户表
LEFT JOIN 
    Orders o              -- 左连接订单表
    ON c.id = o.customerId  -- 连接条件:客户ID匹配
WHERE 
    o.id IS NULL;         -- 过滤条件:无关联订单(订单ID为NULL)

代码说明

  1. LEFT JOIN

    • 保留 Customers 表的所有记录,即使 Orders 表中无匹配。
    • 无订单的客户在连接后,Orders 表的所有列均为 NULL
  2. 过滤条件

    • WHERE o.id IS NULL 精确筛选出无订单的客户(因 Orders.id 是主键,非空;若连接后为 NULL 即表示无订单)。
  3. 列名处理

    • 结果列命名为 Customers 以符合题目要求。
  4. 执行优化

    • 利用索引快速匹配连接条件(Customers.idOrders.customerId)。
    • 避免全表扫描,仅需单次遍历即可完成过滤。

性能关键

  • 索引确保连接操作高效(O(N log M) 复杂度)。
  • LEFT JOINNOT IN 或子查询更节省内存,避免创建临时结果集。

提交详情(执行用时、内存消耗)

在这里插入图片描述

我的名片👇👇👇👇👇👇👇👇👇👇👇

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值