3

次の表のようなものを返すselectクエリがあります。

開始| 停止| id
------------------
0 | 100 | 1
1 | 101 | 1
2 | 102 | 1
2 | 102 | 2
5 | 105 | 1
7 | 107 | 2
..。
300 | 400 | 1
370 | 470 | 1
450 | 550 | 1

ここで、stop = start + n; この場合、n=100です。

各IDのオーバーラップをマージしたいと思います。

開始| 停止| id
------------------
0 | 105 | 1
2 | 107 | 2
..。
300 | 550 | 1

開始300は停止105の後にあるため、id1は0〜550を与えません。

最初のクエリで返されるレコードは数十万になり、nは最大で数万になる可能性があるため、処理が高速であるほど優れています。

PostgreSQLを使用します。

4

1 に答える 1

3
WITH    bounds AS
        (
        SELECT  *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY start) AS rn
        FROM    (
                SELECT  id, LAG(stop) OVER (PARTITION BY id ORDER BY start) AS pstop, start
                FROM    q
                UNION ALL
                SELECT  id, MAX(stop), NULL
                FROM    q
                GROUP BY
                        id
                ) q2
        WHERE   start > pstop OR pstop IS NULL OR start IS NULL
        )
SELECT  b2.start, b1.pstop
FROM    bounds b1
JOIN    bounds b2
ON      b1.id = b2.id
        AND b1.rn = b2.rn + 1
于 2010-11-09T14:55:38.023 に答える