考虑一个包含104行的学生表。我需要创建每组至少10名学生的小组。在有104名学生的情况下,如果我对每个学生进行迭代并创建分组,我最终会得到10组10名学生和1组4名学生。有一个规则是,剩下学生的小组中不能少于5名学生(在这种情况下,最后一组由4名学生组成)。我正试图做的两种可能的方法:
我如何实现这些目标?非常感谢。
埃里克
答案 0 :(得分:2)
您可以使用ntile。
将有序分区中的行分配到指定的数字 团体这些组从一开始编号。对于每一行, NTILE返回该行所属的组的编号。
一些示例代码:
declare @NumberOfStudents int
declare @StudentsPerGroup int
set @StudentsPerGroup = 10
set @NumberOfStudents = 104
select StudentID,
ntile(@NumberOfStudents / @StudentsPerGroup) over(order by StudentID) as GroupID
from Students
在SE-Data上试用。
答案 1 :(得分:0)
这是变体2.第一部分准备计数器。由于我没有关于学生的任何数据,我决定创建一个只有一个列ID的@maxStudents行的临时表。
第一个cte(学生)生成一个maxStudents行的学生列表。秒提取学生为他们分配行号(显然这里没有必要,但在插入检索学生的查询时必不可少)。它还会返回学生人数。
第三部分将学生分成小组。属于最后一组的学生将被重新安置到另一组,如果他们属于具有少于@minGroupSize成员的最后一组。第一版可以通过将例如1的case语句替换为第1组来实现。
declare @group_size int
set @group_size = 10
declare @maxStudents int
set @maxStudents = 104
declare @minGroupSize int
set @minGroupSize = 5
;with students as (
select 1 id
union all
select 2 * id + b
from students cross join (select 0 b union all select 1) b
where 2 * id + b <= @maxStudents
),
s as (
select students.id, row_number() over(order by students.id) - 1 rowNumber, count (*) over () TotalStudents
from students
)
select s.id StudentID,
case when TotalStudents % @group_size < @minGroupSize
and rowNumber >= (TotalStudents / @group_size * @group_size)
then rowNumber - (TotalStudents / @group_size * @group_size)
else rowNumber / @group_size
end + 1 Group_number
from s
order by 2, 1