按最大行数批量SQL Server结果

时间:2014-08-27 23:51:59

标签: sql sql-server sql-server-2008

我需要将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

1 个答案:

答案 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 |