贝利信息

SQL 如何统计 Top N 并合并“其他”?

日期:2026-01-20 00:00 / 作者:冷漠man
SQL统计Top N并归并“其他”的核心是用UNION ALL拼接两部分:先取排序前N行,再将剩余数据聚合为一行“其他”;需确保字段数、类型、顺序一致,避免重复计算且排序稳定。

SQL 统计 Top N 并把剩余归为“其他”,核心是用 UNION ALL 拼接两部分:前 N 行 + 剩余行聚合为一行“其他”。关键在于避免重复计算、保证排序一致、正确汇总“其他”值。

先取 Top N,再算“其他”的总量

标准做法是写两个子查询,用 UNION ALL 合并:

示例(统计销量前 3 的商品,其余归为“其他”):

SELECT product, sales FROM (
  SELECT product, sales, ROW_NUMBER() OVER (ORDER BY sales DESC) AS rn
  FROM orders
) t WHERE rn <= 3

UNION ALL

SELECT '其他' AS product, SUM(sales) AS sales
FROM orders
WHERE product NOT IN (
  SELECT product FROM (
    SELECT product, ROW_NUMBER() OVER (ORDER BY sales DESC) AS rn
    FROM orders
  ) t WHERE rn <= 3
);

用条件聚合一步实现(更简洁,适合简单场景)

如果只关心一个汇总指标(比如总销售额),可用 CASE + SUM 配合窗口函数,避免多次扫描表:

示例(返回 4 行:3 个商品 + 1 行“其他”):

WITH ranked AS (
  SELECT product, sales,
         ROW_NUMBER() OVER (ORDER BY sales DESC) AS rn
  FROM orders
)
SELECT 
  CASE WHEN rn <= 3 THEN product ELSE '其他' END AS product,
  SUM(sales) AS sales
FROM ranked
GROUP BY CASE WHEN rn <= 3 THEN product ELSE '其他' END
ORDER BY MAX(CASE WHEN rn <= 3 THEN rn END) NULLS LAST;

注意去重与并列情况

真实数据常有相同销量的商品,直接用 ROW_NUMBER() 会强行分先后,可能漏掉并列第 3 名。这时建议改用:

不同数据库的语法微调

MySQL 8.0+、PostgreSQL、SQL Server 2017+ 都支持窗口函数,写法基本一致。但注意:

不复杂但容易忽略细节,关键是理清逻辑顺序:排名 → 切分 → 分别聚合 → 对齐字段合并。