如何计算连续数字的数量

时间:2014-01-18 09:07:21

标签: sql sql-server tsql

我有一个名为'Waybill.WaybillRepository'的sql server表,其中包含名为'Id'和'WaybillNumber'的列, 这个表有一些如下所示的行:

Id  Stock Number
--------------------------
1   8150312268
2   8150312269
3   8150312270
4   8150312272
5   8150312273

现在我该如何计算连续数字的数量并显示每个连续的第一个数字和最后一个数字,如下所示:

Row From            To          Count
--------------------------------------------------
1   8150312268  8150312270  3
2   8150312272  8150312273  2

我的查询就是这个,

SELECT  GroupID         = (y.WaybillNumber - y.Id),
        FromWaybillNumber   = MIN(y.WaybillNumber),
        ToWaybillNumber = MAX(y.WaybillNumber),
        Cnt             = COUNT(*)
FROM (
    SELECT  x.Id, x.WaybillNumber, ROW_NUMBER() OVER(ORDER BY x.Id) AS RowNum
    FROM    Waybill.WaybillRepository x
) y
GROUP BY (y.WaybillNumber - y.Id)

但是它的输出是错误的,它知道在这个范围之间有一个数字已删除但没有正确显示

Row From            To          Count
--------------------------------------------------
1   8150312268  8150312273  5

终于有效了 我的疑问是:

SELECT  GroupID         = (y.WaybillNumber - RowNum),
        FromWaybillNumber   = MIN(y.WaybillNumber),
        ToWaybillNumber = MAX(y.WaybillNumber),
        Cnt             = COUNT(*)
FROM (
    SELECT  x.Id, x.WaybillNumber, ROW_NUMBER() OVER(ORDER BY x.Id) AS RowNum
    FROM    Waybill.WaybillRepository x
) y
GROUP BY (y.WaybillNumber - RowNum)

1 个答案:

答案 0 :(得分:2)

了解表名;

;WITH rCTE AS
(

    SELECT *
            ,SequenceGroup  = 1
    FROM Repository   BD
    WHERE ID = 1
    UNION ALL
    SELECT   BD.*
            ,SequenceGroup  = CASE WHEN BD.StockNumber - R.StockNumber = 1 THEN R.SequenceGroup ELSE R.SequenceGroup + 1 END 
    FROM rCTE       R
    JOIN BaseData   BD ON R.ID = BD.ID - 1  
)
SELECT   FromSN = MIN(StockNumber)
        ,ToSN   = MAX(StockNumber)
        ,nCount = COUNT(*)
FROM rCTE
GROUP BY SequenceGroup
OPTION (MAXRECURSION 0)

喜欢这个。

;WITH BaseData (ID, StockNumber) AS
(
    SELECT 1   ,8150286403 UNION ALL
    SELECT 2   ,8150286404 UNION ALL
    SELECT 3   ,8150286405 UNION ALL
    SELECT 4   ,8150286406 UNION ALL
    SELECT 5   ,8150286407 UNION ALL
    SELECT 6   ,8150286408 UNION ALL
    SELECT 7   ,8150286409 UNION ALL
    SELECT 8   ,8150286410 UNION ALL
    SELECT 9   ,8150286411 UNION ALL
    SELECT 10  ,8150286412 UNION ALL
    SELECT 11  ,8150286413 UNION ALL
    SELECT 12  ,8150286414 UNION ALL
    SELECT 13  ,8150286415 UNION ALL
    SELECT 14  ,8150286416 UNION ALL
    SELECT 15  ,8150286417 UNION ALL
    SELECT 16  ,8150286418 UNION ALL
    SELECT 17  ,8150286419 UNION ALL
    SELECT 18  ,8150286420 UNION ALL
    SELECT 19  ,8150286421 UNION ALL
    SELECT 20  ,8150286422 UNION ALL
    SELECT 21  ,8150286423 UNION ALL
    SELECT 22  ,8150286424 UNION ALL
    SELECT 23  ,8150286425 UNION ALL
    SELECT 24  ,8150286426 UNION ALL
    SELECT 25  ,8150286427 UNION ALL
    SELECT 26  ,8150286428 UNION ALL
    SELECT 27  ,8150286429 UNION ALL
    SELECT 28  ,8150286430 UNION ALL
    SELECT 29  ,8150286431 UNION ALL
    SELECT 30  ,8150286432 UNION ALL
    SELECT 31  ,8150286433 UNION ALL
    SELECT 32  ,8150286434 UNION ALL
    SELECT 33  ,8150286435 UNION ALL
    SELECT 34  ,8150286436 UNION ALL
    SELECT 35  ,8150286437 UNION ALL
    SELECT 36  ,8150286438 UNION ALL
    SELECT 37  ,8150286439 UNION ALL
    SELECT 38  ,8150286440 UNION ALL
    SELECT 39  ,8150286441 UNION ALL
    SELECT 40  ,8150286442 UNION ALL
    SELECT 41  ,8150286443 UNION ALL
    SELECT 42  ,8150286444 UNION ALL
    SELECT 43  ,8150286445 UNION ALL
    SELECT 44  ,8150286446 UNION ALL
    SELECT 45  ,8150286447 UNION ALL
    SELECT 46  ,8150286448 UNION ALL
    SELECT 47  ,8150286449 UNION ALL
    SELECT 48  ,8150286450 UNION ALL
    SELECT 49  ,8150286451 UNION ALL
    SELECT 50  ,8150286452 UNION ALL
    SELECT 51  ,8150286453 UNION ALL
    SELECT 52  ,8150286454 UNION ALL
    SELECT 53  ,8150286455 UNION ALL
    SELECT 54  ,8150286456 UNION ALL
    SELECT 55  ,8150286457 UNION ALL
    SELECT 56  ,8150286458 UNION ALL
    SELECT 57  ,8150286459 UNION ALL
    SELECT 58  ,8150286460 UNION ALL
    SELECT 59  ,8150286461 UNION ALL
    SELECT 60  ,8150286462 UNION ALL
    SELECT 61  ,8150286463 UNION ALL
    SELECT 62  ,8150286464 UNION ALL
    SELECT 63  ,8150286465 UNION ALL
    SELECT 64  ,8150286466 UNION ALL
    SELECT 65  ,8150286467 UNION ALL
    SELECT 66  ,8150286468 UNION ALL
    SELECT 67  ,8150286469 UNION ALL
    SELECT 68  ,8150286470 UNION ALL
    SELECT 69  ,8150286471 UNION ALL
    SELECT 70  ,8150286472 UNION ALL
    SELECT 71  ,8150286473 UNION ALL
    SELECT 72  ,8150286474 UNION ALL
    SELECT 73  ,8150286475 UNION ALL
    SELECT 74  ,8150286476 UNION ALL
    SELECT 75  ,8150286477 UNION ALL
    SELECT 76  ,8150286478 UNION ALL
    SELECT 77  ,8150286479 UNION ALL
    SELECT 78  ,8150286480 UNION ALL
    SELECT 79  ,8150286481 UNION ALL
    SELECT 80  ,8150286482 UNION ALL
    SELECT 81  ,8150286483 UNION ALL
    SELECT 82  ,8150286484 UNION ALL
    SELECT 83  ,8150286485 UNION ALL
    SELECT 84  ,8150286486 UNION ALL
    SELECT 85  ,8150286487 UNION ALL
    SELECT 86  ,8150286488 UNION ALL
    SELECT 87  ,8150286489 UNION ALL
    SELECT 88  ,8150286490 UNION ALL
    SELECT 89  ,8150286491 UNION ALL
    SELECT 90  ,8150286492 UNION ALL
    SELECT 91  ,8150286493 UNION ALL
    SELECT 92  ,8150286494 UNION ALL
    SELECT 93  ,8150286495 UNION ALL
    SELECT 94  ,8150286496 UNION ALL
    SELECT 95  ,8150286497 UNION ALL
    SELECT 96  ,8150286498 UNION ALL
    SELECT 97  ,8150286499 UNION ALL
    SELECT 98  ,8150286500 UNION ALL
    SELECT 99  ,8150306413 UNION ALL
    SELECT 100 ,8150306417 UNION ALL
    SELECT 101 ,8150306418 UNION ALL
    SELECT 102 ,8150306419 UNION ALL
    SELECT 103 ,8150306420
)
,rCTE AS
(

    SELECT *
            ,SequenceGroup  = 1
    FROM BaseData   BD
    WHERE ID = 1
    UNION ALL
    SELECT   BD.*
            ,SequenceGroup  = CASE WHEN BD.StockNumber - R.StockNumber = 1 THEN R.SequenceGroup ELSE R.SequenceGroup + 1 END 
    FROM rCTE       R
    JOIN BaseData   BD ON R.ID = BD.ID - 1  
)
SELECT   FromSN = MIN(StockNumber)
        ,ToSN   = MAX(StockNumber)
        ,nCount = COUNT(*)
FROM rCTE
GROUP BY SequenceGroup
OPTION (MAXRECURSION 0)