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

SQL Developer 查询先购买产品A后购买产品B的客户ID

SQL实现方案

要实现的筛选逻辑本质是匹配「同客户下存在产品A的购买记录早于产品B的购买记录」的场景,以下两种方案都可以直接得到正确结果:

方案1:自连接匹配(逻辑直观易调试)

将同一张购买表分别筛选出A的购买子集、B的购买子集做内连接,直接匹配同客户下B交易时间晚于A的记录,去重后即可得到目标客户ID:

SELECT DISTINCT a.`customer ID`
FROM Purchase a
JOIN Purchase b
  ON a.`customer ID` = b.`customer ID`
  AND a.`Product ID` = 'A'
  AND b.`Product ID` = 'B'
  -- 以下日期转换根据你的数据库类型调整,字段本身是日期类型可直接比较
  AND STR_TO_DATE(b.`Transaction Date`, '%d/%m/%Y') > STR_TO_DATE(a.`Transaction Date`, '%d/%m/%Y')

这个写法逻辑非常直白,排查问题时可以直接去掉DISTINCT查看匹配到的交易对,适合数据量中等的场景。

方案2:聚合判断(大表性能更优)

不需要做表关联,直接按客户分组聚合,通过条件聚合判断客户是否同时买过A、B,且B的最早购买时间晚于A的最早购买时间:

SELECT `customer ID`
FROM Purchase
GROUP BY `customer ID`
HAVING
  SUM(`Product ID` = 'A') > 0
  AND SUM(`Product ID` = 'B') > 0
  AND MIN(CASE WHEN `Product ID` = 'B' THEN STR_TO_DATE(`Transaction Date`, '%d/%m/%Y') END)
    > MIN(CASE WHEN `Product ID` = 'A' THEN STR_TO_DATE(`Transaction Date`, '%d/%m/%Y') END)

这个写法只需要全表扫描一次,在百万级以上数据量的场景下性能远好于自连接方案。判断逻辑完全成立:只要客户最早购买B的时间晚于最早购买A的时间,就必然满足B购买晚于A的要求;如果最早的B购买时间早于A,后续所有B的购买时间都不会早于这个最早时间,不会出现漏判。


注意事项

  • 如果Transaction Date字段本身已经是DATE/DATETIME类型,不需要加任何日期转换函数,直接比较字段即可
  • 日期转换语法需要匹配你使用的数据库,不要直接套用MySQL的STR_TO_DATE:
    • PostgreSQL 用 TO_DATE("Transaction Date", 'DD/MM/YYYY')
    • SQL Server 用 CONVERT(DATE, "Transaction Date", 103)
  • 两种方案在提供的样例数据上执行,都会正确返回jones、blogs两个客户,客户lane因为没有购买产品B,会被直接过滤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:39:14