2014-08-27 39 views
1

我需要將SQL結果集分成具有最大行數的批處理。這將超出75M +行的表格,所以很多簡單的解決方法(例如使用Excel或While循環)都不起作用。按最大行數批處理SQL Server結果

下將設置一個例子:

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相同以下。通過PERSONID分區

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

首先使用ROW_NUMBER以獲取每當遇到新的PERSONID是重置回1各行的排名。然後你可以將它除以3(或任何你想要的批量大小的數字),並使用floor函數將結果數字平整爲整數。您現在每行都有一個批次ID,但當它到達新的personID時,它仍會重置爲1,因此您尚未完成。然後,您可以執行一個dense_rank(),它通過personid加上我們的新「batchid_person_specific」列進行排名,併爲所有行獲取全局批處理ID。

的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 | 
+0

感謝您的幫助,這個偉大的 - 它完美的作品!我在'with'語句前添加了一個分號以使SQL更快樂 - SQL Fiddle並不關心,但SSMS 2008似乎在某些時候。 – Nicknow 2014-08-28 02:29:26

+0

沒問題。分號在sql語句的末尾不是開頭,因此您的分號問題可能意味着您在同一個工作表中缺少結尾分號的前一個sql語句。 – ivanatpr 2014-08-29 20:13:22