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

求跨MSSQL与Oracle的高效SQL查询:按id取最小group及对应列

问题描述

原始数据表

idgrouprecno
10011
10012
10033
10034
10125
10136
10217

查询需求

提取去重后的id,每个id对应最小的group值,同时返回该最小group对应的recno列。

期望结果

idgrouprecno
10011
10125
10217

现有查询的局限

如果不需要返回recno,可以用以下语句:

SELECT id, MIN(group)
FROM your_table
WHERE group > 0
GROUP BY id;

但加入recno列后,会因聚合函数规则限制导致报错。

额外要求

  • 目标表数据量超50万条,需保证查询效率
  • 需兼容MSSQL和Oracle(优先遵循ANSI 92标准,分库实现也可)
  • 仅允许使用SQL语句,禁止存储过程

解决方案

方法一:ANSI标准窗口函数(双库兼容)

使用ROW_NUMBER()窗口函数,按id分组后,以group升序、recno升序排序,取每组第一条记录:

SELECT id, "group", recno
FROM (
    SELECT 
        id, 
        "group", 
        recno,
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY "group" ASC, recno ASC) AS rn
    FROM your_table
    WHERE "group" > 0
) t
WHERE rn = 1;

优化说明

  • 建议在表上创建复合索引(id, "group", recno),让数据库能直接通过索引完成排序和筛选,大幅提升大数据量下的查询速度
  • 若同一id和最小group存在多条记录,该语句会取recno最小的那条,与期望结果完全匹配

方法二:关联子查询(ANSI兼容)

先通过子查询获取每个id的最小group,再关联原表筛选对应记录,并取该组内最小的recno:

SELECT t.id, t."group", t.recno
FROM your_table t
INNER JOIN (
    SELECT id, MIN("group") AS min_group
    FROM your_table
    WHERE "group" > 0
    GROUP BY id
) g ON t.id = g.id AND t."group" = g.min_group
WHERE t.recno = (
    SELECT MIN(recno) 
    FROM your_table 
    WHERE id = t.id AND "group" = g.min_group
);

优化说明

  • 同样需要创建(id, "group", recno)复合索引来保障性能,避免全表扫描

数据库专属优化方案(可选)

Oracle 专属写法

利用KEEP子句直接在聚合查询中获取对应recno:

SELECT 
    id,
    MIN("group") AS "group",
    MIN(recno) KEEP (DENSE_RANK FIRST ORDER BY "group" ASC) AS recno
FROM your_table
WHERE "group" > 0
GROUP BY id;

MSSQL 专属写法

使用TOP 1 WITH TIES简化窗口函数写法:

SELECT TOP 1 WITH TIES
    id, [group], recno
FROM your_table
WHERE [group] > 0
ORDER BY ROW_NUMBER() OVER (PARTITION BY id ORDER BY [group] ASC, recno ASC);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:00:36