Reputation: 33
I have a table A
with 2 columns - Roll
and Subject
. It contains these rows:
Roll Subject
1 Robots
2 Robots
3 Robots
4 Robots
5 Robots
6 Space
7 Space
8 Space
9 Space
10 Neurons
11 Neurons
I need to write a query and produce output as follows:
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
Upvotes: 0
Views: 79
Reputation: 14209
Try the following.
The -1
before the ROW_NUMBER
is used so that the ROW_NUMBER
values 1, 2 and 3 (which will be 0, 1 and 2) are grouped together when divided by 3, since the result is 0 (INT
division).
The minimum roll by subject is to split the DENSE_RANK
so it gets a new GroupID
number when the subject changes.
;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
Result:
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
Upvotes: 1
Reputation: 14926
No just simple grouping but grouping max limit is 3
I don't understand the logic here, but according to your comment I think you are looking for
SELECT *,
((ROW_NUMBER() OVER(ORDER BY (SELECT 1)) - 1) / 3) + 1 GroupId
FROM T
Returns:
+------+---------+---------+
| 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 |
+------+---------+---------+
Upvotes: 1
Reputation: 21
This is what you expect
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])
Upvotes: 0