SQL Serverを使用して範囲値をグループ化する方法
-
19-08-2019 - |
質問
このような値の表があります
978412, 400
978813, 20
978834, 50
981001, 20
ご覧のように、最初の数字に追加された2番目の数字は、シーケンスの次の数字の1つ前の数字です。最後の数値は範囲内にありません(次の値のように、直接のシーケンスに従いません)。必要なのは、これを出力するCTE(はい、理想的には)です
978412, 472
981001, 20
最初の行には、範囲の開始番号と、その中のノードの合計が含まれます。次の行は次の範囲で、この例では元のデータと同じです。
解決
Joshが投稿した記事から、以下が私のテストです(テスト済みおよび動作中):
SELECT
MAX(t1.gapID) as gapID,
t2.gapID-MAX(t1.gapID)+t2.gapSize as gapSize
-- max(t1) is the specific lower bound of t2 because of the group by.
FROM
( -- t1 is the lower boundary of an island.
SELECT gapID
FROM gaps tbl1
WHERE
NOT EXISTS(
SELECT *
FROM gaps tbl2
WHERE tbl1.gapID = tbl2.gapID + tbl2.gapSize + 1
)
) t1
INNER JOIN ( -- t2 is the upper boundary of an island.
SELECT gapID, gapSize
FROM gaps tbl1
WHERE
NOT EXISTS(
SELECT * FROM gaps tbl2
WHERE tbl2.gapID = tbl1.gapID + tbl1.gapSize + 1
)
) t2 ON t1.gapID <= t2.gapID -- For all t1, we get all bigger t2 and opposite.
GROUP BY t2.gapID, t2.gapSize
他のヒント
この MSDNの記事をご覧ください。問題の解決策を提供します。問題が解決するかどうかは、保有するデータ量とクエリのパフォーマンス要件によって異なります。
編集:
クエリの例を使用して、最後の解決策でアイランドを取得する2番目の方法を実行します(最初の方法ではSQL 2005でエラーが発生しました)。
SELECT MIN(start) AS startGroup, endGroup, (endgroup-min(start) +1) as NumNodes
FROM (SELECT g1.gapID AS start,
(SELECT min(g2.gapID) FROM #gaps g2
WHERE g2.gapID >= g1.gapID and NOT EXISTS
(SELECT * FROM #gaps g3
WHERE g3.gapID - g2.gapID = 1)) as endGroup
FROM #gaps g1) T1 GROUP BY endGroup
追加したものは(endgroup-min(start) +1) as NumNodes
です。これによりカウントが得られます。
所属していません StackOverflow