12

次の定義を持つテーブルがあります

CREATE TABLE mytable
  (
     id     INT IDENTITY(1, 1) PRIMARY KEY,
     number BIGINT,
     status INT
  )

およびサンプルデータ

INSERT INTO mytable
VALUES (100,0),
       (101,0),
       (102,0),
       (103,0),
       (104,1),
       (105,1),
       (106,0),
       (107,0),
       (1014,0),
       (1015,0),
       (1016,1),
       (1017,0)

行だけを見て、status = 0どのようにNumber値を連続した連続番号の範囲に折りたたんで、各範囲の開始と終了を見つけることができますか?

つまり、サンプルデータの場合、結果は次のようになります

         FROM      to 
Number    100      103
Number    106      107
Number    1014     1015
Number    1017     1017
4

1 に答える 1

33

コメントで述べたように、これは古典的なギャップと島の問題です。

Itzik Ben Gan によって広められた解決策はROW_NUMBER() OVER (ORDER BY number) - number、「島」内で一定のままであり、複数の島には現れないという事実を利用することです。

WITH T
     AS (SELECT ROW_NUMBER() OVER (ORDER BY number) - number AS Grp,
                number
         FROM   mytable
         WHERE  status = 0)
SELECT MIN(number) AS [From],
       MAX(number) AS [To]
FROM   T
GROUP  BY Grp
ORDER  BY MIN(number) 

注意:numberが一意であることが保証されていない場合は、上記のコードで に置き換えROW_NUMBERてください。DENSE_RANK

于 2013-06-11T14:34:03.640 に答える