SQL Server按部门分组,生成每组最多5个唯一员工的结果集查询
解决按部门拆分唯一员工为最多5人一组的SQL问题
嘿,我明白你的需求了!你现在需要把每个部门的唯一员工(从例子来看,重复的EmpName算同一个员工)分成最多5人一组,并且给这些分组分配连续的全局ResultSetNumber。你之前用的DENSE_RANK() OVER (ORDER BY DeptId ASC)是全局按部门排号,完全没考虑部门内的员工拆分逻辑,所以肯定满足不了需求。
核心思路拆解
要实现这个需求,我们需要分三步走:
- 提取每个部门的唯一员工:因为重复的员工(比如Dept100里的两个A)属于同一个主体,所以先对每个部门的
EmpName去重。 - 给部门内的唯一员工分组:给每个部门的唯一员工按顺序排号,然后每5个划分为一组(用
CEILING()函数计算分组号)。 - 生成全局连续的结果集编号:把每个部门的分组转换成全局连续的编号,确保不同部门的分组编号是连贯的。
最终SQL查询语句
WITH UniqueEmployees AS ( -- 第一步:提取每个部门的唯一员工(按EmpName去重) SELECT DISTINCT EmpName, DeptId FROM dbo.Employee ), DeptInternalGroups AS ( -- 第二步:给每个部门内的唯一员工分配组号,每5个一组 SELECT EmpName, DeptId, -- 用CEILING计算分组:前5个为组1,6-10为组2,以此类推 CEILING(DENSE_RANK() OVER (PARTITION BY DeptId ORDER BY EmpName) / 5.0) AS DeptGroupNum FROM UniqueEmployees ), GlobalResultSetNumbers AS ( -- 第三步:将部门内的组号转换为全局连续的ResultSetNumber SELECT DeptId, EmpName, DENSE_RANK() OVER (ORDER BY DeptId, DeptGroupNum) AS ResultSetNumber FROM DeptInternalGroups ) -- 关联原表,得到每个员工对应的结果集编号 SELECT e.EmpId, e.EmpName, e.DeptId, gr.ResultSetNumber FROM dbo.Employee e JOIN GlobalResultSetNumbers gr ON e.DeptId = gr.DeptId AND e.EmpName = gr.EmpName ORDER BY gr.ResultSetNumber, e.EmpId;
语句验证(对应你的示例数据)
- Dept100的唯一员工有7个(A,B,C,D,E,F,G):前5个(A,B,C,D,E)属于组1(
ResultSetNumber=1),剩下的F、G属于组2(ResultSetNumber=2)。 - Dept200的唯一员工有2个(H,J):全部属于组1(
ResultSetNumber=3)。 - Dept300的唯一员工有5个(C,K,A,S,M):全部属于组1(
ResultSetNumber=4)。
最终输出完全匹配你给出的期望结果。
小提示
如果你的“唯一员工”判断标准不是EmpName而是EmpId(即每个EmpId都是独立员工),只需要把UniqueEmployees里的DISTINCT EmpName, DeptId改成DISTINCT EmpId, EmpName, DeptId,然后后续的排序和关联调整为基于EmpId即可。
内容的提问来源于stack exchange,提问作者sushil suthar
相关产品推荐
相关产品推荐

