按SQL Server中每个结果集的记录数进行分组

时间:2019-02-27 14:32:55

标签: sql sql-server

我有一个employee表,如下所示,其中有departmentid作为department表的外键。

我需要按department将他们与5名唯一的员工分组。一个部门中可以有多名员工,但一组中不能超过5名。

例如,对于部门ID为100的公司,有7位唯一的员工,因此应该有两组。

同样,对于部门编号200来说,只有2位唯一的员工,因此这里只有1位员工

将在下面的输出中生成什么查询?

到目前为止,我已经尝试了以下查询

SELECT 
    EmpId, EmpName, DeptId,
    DENSE_RANK() OVER (ORDER BY DeptId ASC) ResultSetNumber
FROM 
    dbo.Employee

上面的查询不适用于5种独特的员工逻辑。

员工表

EmpId  | EmpName | DeptId
-------+---------+--------        
1            A       100
2            B       100
3            C       100
4            D       100
5            E       100
6            A       100
7            B       100
8            F       100
9            G       100
10           H       200
11           J       200
12           C       300
13           K       300
14           A       300
15           S       300
16           M       300

我需要下面的输出。

EmpId  | EmpName | DeptId  | ResultSetNumber
-------+---------+---------+------------------
1            A       100       1
2            B       100       1
3            C       100       1
4            D       100       1
5            E       100       1
6            A       100       1
7            B       100       1
8            F       100       2
9            G       100       2
10           H       200       3
11           J       200       3
12           C       300       4
13           K       300       4
14           A       300       4
15           S       300       4
16           M       300       4

2 个答案:

答案 0 :(得分:2)

这是一次尝试。

DECLARE @T TABLE(EmpId INT, EmpName NVARCHAR(10), DeptId INT)
INSERT @T VALUES
(1,'A',100),(2,'B',100),(3,'C',100),(4,'D',100),(5,'E',100),
(6,'A',100),(7,'B',100),(8,'F',100),(9,'G',100),(10,'H',200),
(11,'J',200),(12,'C',300),(13,'K',300),(14,'A',300),(15,'S',300),
(16,'M',300)--,(17,'Z',100)

SELECT
  EmpId,EmpName,DeptId,
  ResultSetNumber = DENSE_RANK() OVER(PARTITION BY 1 ORDER BY GroupNumber + RankInGroup)
FROM
(
  SELECT  
      EmpId,EmpName,DeptId,
      RankInGroup = (DENSE_RANK() OVER(PARTITION BY DeptId ORDER BY EmpName) / 6) + 1,
      GroupNumber = RANK() OVER(PARTITION BY 1 ORDER BY DeptId) 
  FROM 
      @T
)AS X
ORDER BY EmpID
GO
EmpId | EmpName | DeptId | ResultSetNumber
----: | :------ | -----: | :--------------
    1 | A       |    100 | 1              
    2 | B       |    100 | 1              
    3 | C       |    100 | 1              
    4 | D       |    100 | 1              
    5 | E       |    100 | 1              
    6 | A       |    100 | 1              
    7 | B       |    100 | 1              
    8 | F       |    100 | 2              
    9 | G       |    100 | 2              
   10 | H       |    200 | 3              
   11 | J       |    200 | 3              
   12 | C       |    300 | 4              
   13 | K       |    300 | 4              
   14 | A       |    300 | 4              
   15 | S       |    300 | 4              
   16 | M       |    300 | 4              

db <>提琴here

答案 1 :(得分:0)

尝试一下-

   select *
        from dbo.Employee emp
        inner join (
          select DeptId, EmpId, ROW_NUMBER() OVER(Partition by DeptId ORDER BY DeptId) ResultSetNumber
          from dbo.Employee
          group by DeptId, EmpId) dep on dep.EmpId = emp.EmpId and emp.DeptId=dep.DeptId
        where dep.ResultSetNumber < 10(can change according to your requirement)