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

SQL中如何按分组取TOP1?替代多次TOP与WHERE查询操作

按分组各取1条记录的高效SQL实现方法

针对你遇到的问题——原查询因A组符合条件数据过多,导致TOP26结果全为A组数据,现需为A-Z每个group各取1条code='11'的记录,以下是两种高效实现方案:

方案一:使用ROW_NUMBER()窗口函数(推荐)

这是最通用且性能最优的方案,只需一次表扫描即可完成分组取数,还能灵活指定每组取哪条记录。

SELECT [date], [group], [code], [pol], [relation]
FROM (
    SELECT 
        [date],
        [group],
        [code],
        [pol],
        [relation],
        -- 按group分组,每组内按date降序取最新记录(可改为ASC取最早)
        ROW_NUMBER() OVER (PARTITION BY [group] ORDER BY [date] DESC) AS rn
    FROM [database].[table1]
    WHERE [group] BETWEEN 'A' AND 'Z' -- 替代IN列表,代码更简洁
      AND code = '11'
) AS ranked_data
WHERE rn = 1;

优势:

  • 仅需一次表扫描,性能高效,避免多次查询的开销
  • 通过ORDER BY可精准控制每组返回的记录(如最新、最早或其他规则)
  • 用BETWEEN 'A' AND 'Z'替代冗长的IN列表,维护更方便

方案二:使用CROSS APPLY(适用于SQL Server)

若你更偏好直观的分组关联逻辑,且group数量较少(这里仅26个),可采用此方案:

SELECT t.[date], t.[group], t.[code], t.[pol], t.[relation]
FROM (
    -- 先获取所有符合条件的group
    SELECT DISTINCT [group]
    FROM [database].[table1]
    WHERE [group] BETWEEN 'A' AND 'Z'
      AND code = '11'
) AS target_groups
CROSS APPLY (
    -- 对每个group取TOP1记录
    SELECT TOP 1 [date], [code], [pol], [relation]
    FROM [database].[table1]
    WHERE [group] = target_groups.[group]
      AND code = '11'
    ORDER BY [date] DESC -- 同样可自定义排序规则
) AS t;

性能优化建议:

  • 为[group]和code创建联合索引(如CREATE INDEX IX_table1_group_code_date ON [database].[table1] ([group], code, [date]);),可避免全表扫描,大幅提升查询速度
  • 若无需指定排序规则,可将ORDER BY改为ORDER BY (SELECT NULL),但此方式返回的记录是随机的,不建议用于需要稳定结果的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:50:39