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

SQL查询问题:按RelationId去重获取用户最近3条有权限操作记录

解决SQL查询中RelationId重复的问题

我来帮你搞定这个问题——你的核心需求是拿到用户有权限、按RelationId去重后的最近3条操作记录,但原SQL里的DISTINCT没起到预期的去重作用,因为它是基于整个Action行的所有字段来判断唯一性的,而每条Action记录的id是唯一的,所以即使RelationId相同,不同的id会被当成不同记录保留下来。

解决方案思路

要实现按RelationId去重(取每个RelationId下最新的操作记录),再关联权限验证,最后分页取前3条,我们可以用窗口函数来精准控制去重逻辑:

  1. 先对Action表按RelationId分组,每组内按TimeStamp倒序排序,标记出每组的最新记录;
  2. 过滤出仅包含每组最新记录的数据集;
  3. 将这个数据集与Permission表关联,验证用户权限;
  4. 最后按时间倒序,用你要求的OFFSET/FETCH语法取前3条。

修正后的SQL语句

SELECT a_filtered.*, p.RelationId
FROM (
    SELECT 
        a.*,
        -- 按RelationId分组,每组内按时间倒序,最新记录标记为1
        ROW_NUMBER() OVER(PARTITION BY a.RelationId ORDER BY a.TimeStamp DESC) AS rn
    FROM [Action] [a]
    WHERE 
        a.ActionType = 'Clicked' 
        AND a.RelationType = 'Direct' 
        AND a.UserId = 5 
        AND a.Deleted = 0
) AS a_filtered
INNER JOIN [Permission] p 
    ON p.RelationId = a_filtered.RelationId 
    AND p.RelationType = a_filtered.RelationType 
    AND p.UserId = a_filtered.UserId 
    AND p.Deleted = 0
-- 只保留每个RelationId下的最新操作记录
WHERE a_filtered.rn = 1
-- 按时间倒序,取最近3条
ORDER BY a_filtered.TimeStamp DESC
OFFSET 0 ROWS FETCH NEXT 3 ROWS ONLY;

逻辑说明

  • 子查询a_filtered中,ROW_NUMBER() OVER(PARTITION BY a.RelationId ORDER BY a.TimeStamp DESC)会给每个RelationId分组内的记录按时间从新到旧编号,最新的那条记录编号为1;
  • 过滤rn = 1就完成了按RelationId去重的核心需求,确保每个RelationId只保留最新的操作记录;
  • 与Permission表的关联条件完全保留了你原SQL中的校验逻辑,确保用户仍具备对应权限;
  • 最后用OFFSET/FETCH实现分页,精准获取最近3条符合要求的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:43:29