2010-11-09 41 views
3

我有一個選擇查詢,將返回的東西如下表所示:減少排在SQL

 
start | stop | 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 

哪裏停止=起動+ N;在這種情況下n = 100。

我想合併重疊每個ID:

 
start | stop | id 
------------------ 
0  | 105 | 1 
2  | 107 | 2 
... 
300 | 550 | 1 

ID 1沒有給出0 - 550,因爲一開始300停止後105

將有幾十萬第一個查詢返回的記錄和n可以達到數萬,所以處理得越快越好。

使用PostgreSQL btw。

+0

你是什麼意思「我想合併每個id的重疊」?你的意思是你只想要第一個出現id的實例嗎? – 2010-11-09 14:40:49

+0

ID 1的範圍是0-100和1-101;這兩排可以減少到0-101等,因爲第二次開始不到第一站。 – FlightOfStairs 2010-11-09 14:44:14

+0

因此,如果在上述數據的省略號中也存在範圍100-200和200-300的id 1,那麼您希望看到0-550的id 1?我們能否認爲省略號內沒有這樣的額外範圍? – 2010-11-09 14:54:34

回答

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

我不完全理解這個查詢,但它有效(並且速度非常快)。 - 乾杯 – FlightOfStairs 2010-11-09 15:22:17