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

按ID筛选记录:有Value=b则取b,否则取最新日期记录

解决按Persid筛选记录:优先取Value=b,无则取最新日期的记录

这个需求用窗口函数就能很优雅地解决,比你之前尝试的GROUP BY统计方法更直接高效。先给你看最终的SQL代码,再一步步拆解逻辑:

示例数据与预期结果

先把你的示例数据整理成清晰格式:
原表(假设表名为your_table):

Persid | Value | Date
1      | a     | 2023-01-01
1      | a     | 2023-01-02
1      | a     | 2023-01-03
2      | b     | 2023-01-01
2      | a     | 2023-01-02
2      | a     | 2023-01-03

预期结果:

Persid | Value | Date
1      | a     | 2023-01-03
2      | b     | 2023-01-01

最优解决方案:使用ROW_NUMBER()窗口函数

WITH ranked_records AS (
    SELECT 
        Persid,
        Value,
        Date,
        -- 给每个Persid的记录排序:优先Value=b的,再按日期倒序
        ROW_NUMBER() OVER (
            PARTITION BY Persid 
            ORDER BY 
                CASE WHEN Value = 'b' THEN 0 ELSE 1 END,
                Date DESC
        ) AS rn
    FROM your_table
)
SELECT Persid, Value, Date
FROM ranked_records
WHERE rn = 1;

代码逻辑拆解

  1. CTEranked_records:给每条记录添加一个行号rn,按Persid分组(也就是每个Persid单独处理)。
  2. 排序规则:
    • 用CASE表达式给Value='b'的记录标记为0,其他为1——这样所有'b'的记录会排在同组最前面(因为0<1)。
    • 对于没有'b'的组,按Date降序排列,最新的日期会自动排在第一位。
  3. 筛选结果:取每个组里rn=1的记录,就是我们要的目标——要么是该Persid任意一条'b'的记录,要么是最新日期的记录。

替代方案(沿用GROUP BY统计思路)

如果你想继续用之前GROUP BY统计的思路,也可以先找出所有存在'b'的Persid,再分别取数:

WITH has_b_persids AS (
    -- 找出所有包含Value=b的Persid
    SELECT DISTINCT Persid
    FROM your_table
    WHERE Value = 'b'
)
-- 取有b的Persid的任意一条b记录
SELECT Persid, Value, MIN(Date) AS Date  -- 用MIN/MAX都可以,仅为取任意一条
FROM your_table
WHERE Persid IN (SELECT Persid FROM has_b_persids) AND Value = 'b'
GROUP BY Persid, Value
UNION ALL
-- 取没有b的Persid的最新日期记录
SELECT t.Persid, t.Value, t.Date
FROM your_table t
LEFT JOIN has_b_persids h ON t.Persid = h.Persid
WHERE h.Persid IS NULL
QUALIFY ROW_NUMBER() OVER (PARTITION BY t.Persid ORDER BY t.Date DESC) = 1;

不过这个方法需要两次查询再合并,效率不如第一种窗口函数方案,推荐优先用第一种。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:24:44