You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用子查询结果,用单条SQL筛选符合订购条件的客户?

解决方案:用单条SQL筛选符合条件的客户

当然可行!你的思路完全没问题——先锁定Smith客户2013年的所有订购产品,再找出2014年覆盖了这些产品的客户。下面我结合常见的电商表结构(假设你有customers、orders、order_items三张表),给你两种实用的实现方式:

方法1:通过计数匹配判断全覆盖

这种方法逻辑直观:先统计Smith 2013年订购的去重产品总数,再统计2014年每个客户订购的这些产品的去重数量,两者相等就说明该客户覆盖了所有目标产品。

SELECT c.customer_id, c.name
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
JOIN order_items oi ON o.order_id = oi.order_id
WHERE YEAR(o.order_date) = 2014
  -- 只关注Smith 2013年订购过的产品
  AND oi.product_id IN (
    SELECT DISTINCT oi_smith.product_id
    FROM customers c_smith
    JOIN orders o_smith ON c_smith.customer_id = o_smith.customer_id
    JOIN order_items oi_smith ON o_smith.order_id = oi_smith.order_id
    WHERE c_smith.name = 'Smith'
      AND YEAR(o_smith.order_date) = 2013
  )
GROUP BY c.customer_id, c.name
-- 客户订购的目标产品数 = Smith的目标产品总数
HAVING COUNT(DISTINCT oi.product_id) = (
    SELECT COUNT(DISTINCT oi_smith.product_id)
    FROM customers c_smith
    JOIN orders o_smith ON c_smith.customer_id = o_smith.customer_id
    JOIN order_items oi_smith ON o_smith.order_id = oi_smith.order_id
    WHERE c_smith.name = 'Smith'
      AND YEAR(o_smith.order_date) = 2013
);

注意点:

  • 必须用COUNT(DISTINCT),避免客户多次订购同一产品导致计数虚高;
  • 如果你的orders表直接包含product_id(不需要order_items),去掉order_items的关联即可。

方法2:用NOT EXISTS反推无遗漏

这种方法逻辑更严谨:找2014年的客户,不存在任何一个Smith 2013年的产品是该客户没订购的。适合产品数量较多、需要高效查询的场景。

SELECT DISTINCT c.customer_id, c.name
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
WHERE YEAR(o.order_date) = 2014
AND NOT EXISTS (
    -- 子查询:检查是否存在Smith的产品,该客户2014年没订购
    SELECT 1
    FROM (
        -- Smith 2013年的所有去重产品
        SELECT DISTINCT oi_smith.product_id
        FROM customers c_smith
        JOIN orders o_smith ON c_smith.customer_id = o_smith.customer_id
        JOIN order_items oi_smith ON o_smith.order_id = oi_smith.order_id
        WHERE c_smith.name = 'Smith'
          AND YEAR(o_smith.order_date) = 2013
    ) smith_products
    WHERE NOT EXISTS (
        -- 检查该客户2014年是否订购了当前Smith的产品
        SELECT 1
        FROM orders o_cust
        JOIN order_items oi_cust ON o_cust.order_id = oi_cust.order_id
        WHERE o_cust.customer_id = c.customer_id
          AND YEAR(o_cust.order_date) = 2014
          AND oi_cust.product_id = smith_products.product_id
    )
);

优势:

  • 不需要额外的计数统计,逻辑上直接对应“至少订购所有产品”的需求;
  • 数据库对NOT EXISTS的优化通常较好,大表查询时性能可能更优。

内容的提问来源于stack exchange,提问作者Bohao LI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:42:46