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

如何不使用子查询,按UserID去重后限制SQL查询行数?

实现按前N个不同用户ID获取所有关联记录

针对你的需求,要高效获取前2个不同用户ID对应的所有猫咪记录,使用窗口函数是最优方案,以下是正确的写法及说明:

错误分析

你原SQL的JOIN条件存在错误:ON U.id = C.id 应该改为 ON U.id = C.userID,否则会错误关联用户ID和猫咪ID,而非用户ID和猫咪所属用户ID。另外直接加LIMIT 2只会返回前2条记录,无法按用户ID分组限制。

正确的窗口函数实现

使用DENSE_RANK()窗口函数为每个用户ID分配排名,再筛选排名≤2的记录,这样能保证获取前2个用户的所有关联猫咪数据,且性能优于子查询IN的方式(尤其适合大表,可利用user.id和cats.userID的索引):

SELECT U.id AS user_id, C.name AS cat_name
FROM user U
INNER JOIN (
    -- 为每个猫咪所属的用户ID按顺序排名
    SELECT 
        name, 
        userID,
        DENSE_RANK() OVER (ORDER BY userID) AS user_rank
    FROM cats
) C ON U.id = C.userID
WHERE C.user_rank <= 2;

逻辑说明

  1. 子查询中,DENSE_RANK() OVER (ORDER BY userID)会按照userID的升序为每个用户分配唯一排名,同一个用户的所有猫咪记录会获得相同的排名。
  2. 外层关联用户表后,筛选排名≤2的记录,即可得到前2个用户的所有猫咪数据。

自定义排序规则

如果需要按用户的其他字段(比如年龄)来选择前2个用户,只需修改窗口函数的排序条件即可,例如按用户年龄升序选前2个:

SELECT U.id AS user_id, C.name AS cat_name
FROM (
    SELECT 
        U.id,
        C.name,
        DENSE_RANK() OVER (ORDER BY U.age) AS user_rank
    FROM user U
    INNER JOIN cats C ON U.id = C.userID
) ranked_data
WHERE ranked_data.user_rank <= 2;

执行结果

以你的表数据为例,执行第一个SQL会得到以下结果:

user_idcat_name
1miez
1caty
2random

这正是你需要的前2个不同用户ID对应的所有记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:31:12