将特定数量的行组合在一起并生成一个组ID

时间:2018-12-11 12:35:37

标签: sql sql-server tsql

我有一个包含两列的表A-RollSubject。它包含以下行:

Roll Subject
 1   Robots
 2   Robots
 3   Robots
 4   Robots
 5   Robots
 6   Space
 7   Space
 8   Space
 9   Space
10   Neurons
11   Neurons

我需要编写查询并产生如下输出:

Roll Subject GroupId
   1 Robots  1
   2 Robots  1
   3 Robots  1
   4 Robots  2
   5 Robots  2
   6 Space   3
   7 Space   3
   8 Space   3
   9 Space   4
  10 Neurons 5
  11 Neurons 5

3 个答案:

答案 0 :(得分:1)

  

不仅仅是简单的分组,分组的最大限制是3

我不理解这里的逻辑,但是根据your comment,我认为您正在寻找

SELECT *, 
      ((ROW_NUMBER() OVER(ORDER BY (SELECT 1)) - 1) / 3) + 1 GroupId
FROM T

返回:

+------+---------+---------+
| Roll | Subject | GroupId |
+------+---------+---------+
|    1 | Robots  |       1 |
|    2 | Robots  |       1 |
|    3 | Robots  |       1 |
|    4 | Robots  |       2 |
|    5 | Robots  |       2 |
|    6 | Space   |       2 |
|    7 | Space   |       3 |
|    8 | Space   |       3 |
|    9 | Space   |       3 |
|   10 | Neurons |       4 |
|   11 | Neurons |       4 |
+------+---------+---------+

Demo

答案 1 :(得分:1)

尝试以下方法。

使用-1之前的ROW_NUMBER,以便将ROW_NUMBER的值1、2和3(将分别为0、1和2)除以3时,将它们分组在一起,因为结果是0(INT分)。

按主题进行的最小滚动是将DENSE_RANK拆分,以便在主题发生变化时获得一个新的GroupID编号。

;WITH SampleData AS
(
    SELECT
        A.Roll,
        A.Subject,
        RowNumberBySubject = -1 + ROW_NUMBER() OVER (PARTITION BY A.Subject ORDER BY A.Roll ASC),
        MinRollBySubject = MIN(A.Roll) OVER (PARTITION BY A.Subject)
    FROM
        (VALUES
            (1,'Robots'),
            (2,'Robots'),
            (3,'Robots'),
            (4,'Robots'),
            (5,'Robots'),
            (6,'Space'),
            (7,'Space'),
            (8,'Space'),
            (9,'Space'),
            (10,'Neurons'),
            (11,'Neurons') 
            ) A(Roll, [Subject])
)
SELECT
    S.Roll,
    S.Subject,
    S.RowNumberBySubject,
    S.MinRollBySubject,
    GroupIDBySubject = S.RowNumberBySubject / 3,
    GroupId = DENSE_RANK() OVER (
        ORDER BY 
            S.MinRollBySubject, 
            S.RowNumberBySubject / 3) -- GroupIDBySubject
FROM
    SampleData AS S
ORDER BY
    S.Roll ASC

结果:

Roll    Subject RowNumberBySubject  MinRollBySubject    GroupIDBySubject    GroupId
1       Robots  0                   1                   0                   1
2       Robots  1                   1                   0                   1
3       Robots  2                   1                   0                   1
4       Robots  3                   1                   1                   2
5       Robots  4                   1                   1                   2
6       Space   0                   6                   0                   3
7       Space   1                   6                   0                   3
8       Space   2                   6                   0                   3
9       Space   3                   6                   1                   4
10      Neurons 0                   10                  0                   5
11      Neurons 1                   10                  0                   5

答案 2 :(得分:0)

这就是您的期望

SELECT *,NTILE(3) OVER(ORDER BY [Roll])AS GroupID FROM 
(
VALUES
(1,'Robots'),
(2,'Robots'),
(3,'Robots'),
(4,'Robots'),
(5,'Robots'),
(6,'Space'),
(7,'Space'),
(8,'Space'),
(9,'Space'),
(10,'Neurons'),
(11,'Neurons') 
)A (Roll,[Subject])