我需要将SQL结果集分解为具有最大行数的批处理。这将是一个包含75M +行的表格,因此许多“简单”的解决方法(例如使用Excel或While循环)都不起作用。
以下将设置一个示例:
CREATE TABLE [dbo].[TeamPersonMap](
[TeamPersonId] [int] IDENTITY(1,1) NOT NULL,
[TeamId] [int] NOT NULL,
[PersonId] [int] NOT NULL
)
GO
DECLARE @itemCount int = 0
WHILE (@itemCount < 5)
BEGIN
SET @itemCount = @itemCount + 1
DECLARE @personId int = 100
WHILE (@personId < 105)
BEGIN
SET @personId = @personId + 1
INSERT INTO TeamPersonMap (TeamId, PersonId) VALUES (@itemCount, @personId)
END
END
现在我们可以运行以下查询:
SELECT DENSE_RANK()OVER (ORDER BY PersonId) as BatchGroupId, *
FROM TeamPersonMap ORDER BY PersonId
这将是结果集:
BatchId TeamPersonId TeamId PersonId
1 1 1 101
1 6 2 101
1 11 3 101
1 16 4 101
1 21 5 101
2 22 5 102
2 17 4 102
2 12 3 102
如果规则说最大批量大小为3且PersonId必须相同,我需要查询以获得如下所示的最终BatchId。
BatchId TeamPersonId TeamId PersonId
1 1 1 101
1 6 2 101
1 11 3 101
2 16 4 101
2 21 5 101
3 22 5 102
3 17 4 102
3 12 3 102
答案 0 :(得分:1)
首先使用由personid分区的row_number来获取每个行的排名,每当遇到新的personid时,该行重置为1。然后你可以将它除以3(或任何你想要的批量大小的数字)并使用a floor函数将得到的数字展平为整数。您现在每行都有一个批次ID,但当它到达新的personID时仍会重置为1,因此您还没有完成。然后你可以做一个按personid排序的dense_rank()加上我们的新&#34; batchid_person_specific&#34;列并获取所有行的全局batchid。
Sql小提琴:http://sqlfiddle.com/#!6/3c75d/18
结果如下:
with qwry as (
SELECT
ROW_NUMBER() OVER (PARTITION BY PersonId order by TeamPersonId) as rownum_nofloor
, floor((ROW_NUMBER() OVER (PARTITION BY PersonId order by TeamPersonId)-1)/3)+1 as batchid_person_specific
, *
FROM TeamPersonMap
)
select
DENSE_RANK() OVER (ORDER BY PersonId, batchid_person_specific) as BatchGroupId_Final
,* from qwry
ORDER BY PersonId
<强> [结果] [2] 强>:
| BATCHGROUPID_FINAL | ROWNUM_NOFLOOR | BATCHID_PERSON_SPECIFIC | TEAMPERSONID | TEAMID | PERSONID |
|--------------------|----------------|-------------------------|--------------|--------|----------|
| 1 | 1 | 1 | 1 | 1 | 101 |
| 1 | 2 | 1 | 6 | 2 | 101 |
| 1 | 3 | 1 | 11 | 3 | 101 |
| 2 | 4 | 2 | 16 | 4 | 101 |
| 2 | 5 | 2 | 21 | 5 | 101 |
| 3 | 1 | 1 | 2 | 1 | 102 |
| 3 | 2 | 1 | 7 | 2 | 102 |
| 3 | 3 | 1 | 12 | 3 | 102 |
| 4 | 4 | 2 | 17 | 4 | 102 |
| 4 | 5 | 2 | 22 | 5 | 102 |
| 5 | 1 | 1 | 3 | 1 | 103 |
| 5 | 2 | 1 | 8 | 2 | 103 |
| 5 | 3 | 1 | 13 | 3 | 103 |
| 6 | 4 | 2 | 18 | 4 | 103 |
| 6 | 5 | 2 | 23 | 5 | 103 |
| 7 | 1 | 1 | 4 | 1 | 104 |
| 7 | 2 | 1 | 9 | 2 | 104 |
| 7 | 3 | 1 | 14 | 3 | 104 |
| 8 | 4 | 2 | 19 | 4 | 104 |
| 8 | 5 | 2 | 24 | 5 | 104 |
| 9 | 1 | 1 | 5 | 1 | 105 |
| 9 | 2 | 1 | 10 | 2 | 105 |
| 9 | 3 | 1 | 15 | 3 | 105 |
| 10 | 4 | 2 | 20 | 4 | 105 |
| 10 | 5 | 2 | 25 | 5 | 105 |