You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

SQL关联查询:当采购记录符合条件时获取客户全部采购记录

解决方法:获取有指定采购记录客户的全部采购数据

你的问题很典型——原SQL的写法是在LEFT JOIN的关联条件里加了日期过滤,这会导致只有符合日期的采购记录会被匹配上,其他采购记录直接被排除了,自然只能看到单条符合条件的记录。要实现“只要客户有任意一条采购符合条件,就返回该客户所有采购记录”的需求,有几种常用的方案:

方案一:用子查询筛选目标客户ID

先找出所有在指定日期有采购的客户,再关联这些客户的全部采购记录:

SELECT c.*, p.*
FROM customer c
JOIN purchase p ON c.id = p.customer_id
WHERE c.id IN (
    -- 先拿到所有在2019-02-01有采购的客户ID
    SELECT customer_id 
    FROM purchase 
    WHERE purchase_date = '2019-02-01'
)

如果需要保留客户信息(即使该客户除了目标日期外没有其他采购记录),可以把JOIN改成LEFT JOIN,不过这种情况返回的采购字段会是NULL,你可以根据实际需求调整。

方案二:用EXISTS子句(性能更优)

EXISTS子查询会在找到第一个匹配项后立即停止检索,在数据量较大时性能比IN更好:

SELECT c.*, p.*
FROM customer c
JOIN purchase p ON c.id = p.customer_id
WHERE EXISTS (
    SELECT 1
    FROM purchase p2
    WHERE p2.customer_id = c.id
      AND p2.purchase_date = '2019-02-01'
)

这里的SELECT 1只是用来确认存在性,不需要返回具体字段,所以效率很高。

方案三:窗口函数(适合复杂场景)

如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server等),可以用窗口函数标记客户是否有目标采购记录,再过滤出符合条件的行:

SELECT *
FROM (
    SELECT c.*, p.*,
           -- 按客户分组,标记该客户是否有符合日期的采购
           MAX(CASE WHEN p.purchase_date = '2019-02-01' THEN 1 ELSE 0 END) OVER (PARTITION BY c.id) AS has_target_purchase
    FROM customer c
    LEFT JOIN purchase p ON c.id = p.customer_id
) sub_query
WHERE has_target_purchase = 1

这种方法的优势是可以在一次扫描中完成标记和过滤,适合需要额外计算客户维度指标的复杂场景。

为什么原SQL不行?

再补充说明下原SQL的问题:你在LEFT JOINON条件里加了purchase.purchase_date = '2019-02-01',这会让数据库只把客户和符合该日期的采购记录关联,其他采购记录不会被匹配,最终要么返回客户+符合条件的采购,要么返回客户+NULL(如果该客户没有符合日期的采购),完全达不到“返回客户全部采购”的目的。

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

火山引擎 最新活动