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

在SQL Server中按指定数量分组ID并生成组内编号与统计

按固定行数分组并生成组内编号、统计组内数量

需求说明

  • 将mytable中的记录按每组4条分组,最后一组允许不足4条
  • 为每组内的行添加组内序号(RowNum)
  • 统计每组包含的ID数量(IdCount)

原代码问题分析

你提供的代码存在几个语法和逻辑错误:

  1. 变量@s不能直接搭配OVER子句,无法生成正确的分组ID
  2. (count Ids in each group)是无效语法,不能这样统计组内数量
  3. GROUP BY t.Id会将每条记录单独分组,违背了按4条一组的需求

正确实现方案

以下是基于SQL Server的可行代码,两种写法任选:

写法1:直接使用窗口函数

DECLARE @s INT = 4;

SELECT
    Id,
    -- 计算分组ID:行号减1后除以每组行数,取整加1得到组号
    ((ROW_NUMBER() OVER (ORDER BY Id ASC) - 1) / @s) + 1 AS GroupId,
    -- 生成组内序号:余数为0时取每组行数,否则取余数
    CASE 
        WHEN ROW_NUMBER() OVER (ORDER BY Id ASC) % @s = 0 THEN @s
        ELSE ROW_NUMBER() OVER (ORDER BY Id ASC) % @s
    END AS RowNum,
    -- 统计每组的记录数
    COUNT(*) OVER (PARTITION BY ((ROW_NUMBER() OVER (ORDER BY Id ASC) - 1) / @s)) AS IdCount
FROM mytable
ORDER BY Id ASC;

写法2:用CTE优化重复计算

如果数据量较大,用CTE先计算全局行号,避免重复调用ROW_NUMBER(),提升效率:

DECLARE @s INT = 4;

WITH RankedData AS (
    SELECT
        Id,
        ROW_NUMBER() OVER (ORDER BY Id ASC) AS RowNumOverall
    FROM mytable
)
SELECT
    Id,
    ((RowNumOverall - 1) / @s) + 1 AS GroupId,
    CASE 
        WHEN RowNumOverall % @s = 0 THEN @s
        ELSE RowNumOverall % @s
    END AS RowNum,
    COUNT(*) OVER (PARTITION BY ((RowNumOverall - 1) / @s)) AS IdCount
FROM RankedData
ORDER BY Id ASC;

说明

  • 分组ID的计算逻辑:行号从1开始,(行号-1)/每组行数会将连续的N条记录归为同一组,加1后得到从1开始的组号
  • 组内序号的逻辑和你原思路一致,确保每组的序号从1到4(最后一组不足4条时到实际数量)
  • COUNT(*) OVER (PARTITION BY 分组字段) 用于按组统计该组的总记录数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:05:24