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

如何通过单条SQL查询获取全量用户对应Top3评分类型的分组记录

合并SQL查询实现需求的方案

当然可以!你完全能把这两步操作合并成单条SQL语句,下面给你几种不同的实现方案,适配不同的数据库方言(比如MySQL、PostgreSQL、SQL Server等),你可以按需选择:

方案1:使用子查询 + IN 子句

这种方式直接在WHERE条件里嵌套子查询,先筛选出总评分排名前三的类型,再过滤原表记录:

SELECT user_id, type, value
FROM ratings
WHERE type IN (
    SELECT type
    FROM ratings
    GROUP BY type
    ORDER BY SUM(value) DESC
    LIMIT 3 -- 注意:不同数据库取前三的语法有差异,SQL Server用TOP 3,Oracle用FETCH FIRST 3 ROWS ONLY
)
ORDER BY user_id, type;

逻辑解释:

  • 内层子查询先按type分组,计算每个类型的总评分SUM(value),按总分降序排序后取前3个类型;
  • 外层查询直接筛选出原表中type属于这前三类型的所有记录,最后按user_id和type排序(可选,让结果更规整)。

方案2:使用CTE(公共表表达式)

CTE能把逻辑拆分得更清晰,可读性更强,适合复杂查询:

WITH TopTypes AS (
    SELECT type
    FROM ratings
    GROUP BY type
    ORDER BY SUM(value) DESC
    LIMIT 3 -- 同样注意数据库语法差异
)
SELECT r.user_id, r.type, r.value
FROM ratings r
JOIN TopTypes tt ON r.type = tt.type
ORDER BY r.user_id, r.type;

逻辑解释:

  • 先定义TopTypes这个临时结果集,用来存储总评分前三的类型;
  • 再将原表ratings和TopTypes通过type关联,得到符合条件的记录。

方案3:使用窗口函数(适用于支持窗口函数的数据库)

如果你的数据库支持窗口函数(比如MySQL 8+、PostgreSQL、SQL Server),可以用这种更灵活的方式,还能处理同分排名的情况:

SELECT user_id, type, value
FROM (
    SELECT 
        r.user_id, r.type, r.value,
        RANK() OVER (ORDER BY SUM(r.value) OVER (PARTITION BY r.type) DESC) AS type_rank
    FROM ratings r
) ranked_records
WHERE type_rank <= 3
ORDER BY user_id, type;

逻辑解释:

  • 内层查询中,SUM(r.value) OVER (PARTITION BY r.type)用来计算每个type的总评分;
  • RANK() OVER (...)根据每个类型的总评分进行排名;
  • 外层查询筛选出排名<=3的记录,得到最终结果。

注意事项

  • 语法差异:不同数据库取前N条的语法不同:
    • MySQL/MariaDB:LIMIT 3
    • SQL Server:SELECT TOP 3 type ...
    • Oracle:SELECT type ... ORDER BY SUM(value) DESC FETCH FIRST 3 ROWS ONLY
  • 同分处理:如果有多个类型的总评分相同,RANK()会给它们相同的排名,可能返回超过3个类型;如果需要严格只取3个,可以改用ROW_NUMBER(),但要确保排序的稳定性(比如再加一个排序字段,比如type)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:17:29