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

如何筛选:存在type=AB时取该类记录,无则取最旧行

解决按user_id筛选记录:优先取type=AB,无则取最早记录

下面给你三种可行的写法,根据你的习惯选就行:

方法1:窗口函数(最直观易维护)

用窗口函数给每个用户的记录排优先级:type=AB的直接排第一,剩下的按日期从早到晚排,最后取每个用户的第一条记录。

SELECT x_id, type, user_id, other_id, date
FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY user_id 
            ORDER BY 
                CASE WHEN type = 'AB' THEN 0 ELSE 1 END, 
                date ASC
        ) AS rn
    FROM your_table
) t
WHERE rn = 1;

这里PARTITION BY user_id把数据按用户分组,ORDER BY里先把AB类型的权重设为0(比其他类型的1优先级高),同优先级的再按日期升序取最早的,最后筛选rn=1就是每个用户的目标记录。

方法2:修正NOT EXISTS的写法

你之前用NOT EXISTS出错,大概率是没把user_id的关联和双重条件卡准。正确的逻辑是:要么这条记录是AB类型,要么(该用户根本没有AB记录,且这条是该用户最早的记录)。

SELECT t1.*
FROM your_table t1
WHERE 
    t1.type = 'AB'
    OR (
        NOT EXISTS (
            SELECT 1 
            FROM your_table t2 
            WHERE t2.user_id = t1.user_id AND t2.type = 'AB'
        )
        AND NOT EXISTS (
            SELECT 1 
            FROM your_table t3 
            WHERE t3.user_id = t1.user_id AND t3.date < t1.date
        )
    );

这个写法里,有AB记录的用户只会返回他们的AB记录,不会带出其他类型;没有AB记录的用户,只会返回他们最早的那条记录。

方法3:UNION ALL分情况合并

把两种场景分开查询再合并,逻辑更直白:

-- 先取所有有AB类型的用户的AB记录
SELECT x_id, type, user_id, other_id, date
FROM your_table
WHERE type = 'AB'

UNION ALL

-- 再取没有AB类型的用户的最早记录
SELECT t1.x_id, t1.type, t1.user_id, t1.other_id, t1.date
FROM your_table t1
WHERE NOT EXISTS (
    SELECT 1 FROM your_table t2 WHERE t2.user_id = t1.user_id AND t2.type = 'AB'
)
AND NOT EXISTS (
    SELECT 1 FROM your_table t3 WHERE t3.user_id = t1.user_id AND t3.date < t1.date
);

因为两种场景的用户集合是完全互斥的(有AB的和没AB的),用UNION ALL合并不会有重复,结果就是你要的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:05:22