2010-11-09 42 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