2017-09-05 47 views
0

我试图找到同时生成的数据中的空白。优化SQL查询(查找数据中的空白)Postgresql

简表看起来像这样:

-------------------- 
| row | date  | 
-------------------- 
| 1 | 2017-01-01 | 
| 2 | 2017-01-02 | 
| 3 | 2017-01-03 | 
| 4 | 2017-02-01 | 
| 5 | 2017-02-04 | 

查询的结果应该是这样的:

------------------------ 
| date  | diff | 
------------------------ 
| 2017-01-03 | 27 days | 

2017年1月3日持续27天的差距已经开始。

我写了这样的查询和它的工作。但是,在较大的数据集(大约20k行)上需要​​很长时间。

SELECT 
    t.date, 
    t.diff 
FROM 
    (WITH sd AS 
     (SELECT * 
     FROM observation 
     WHERE nr_id='7810' 
      AND date BETWEEN '2014-01-01' AND '2014-12-31' 
     ORDER BY date ASC) SELECT c.date, 
            coalesce(n.date, NULL) - c.date AS diff 
    FROM sd AS c 
    LEFT JOIN sd AS n ON n.date = 
     (SELECT MIN(date) 
     FROM sd WHERE date > c.date)) AS t 
WHERE t.diff > '6 days' 

有没有人有任何其他想法,如何更有效地写它?

ANSWER(修改的方法由戈登·利诺夫发送):

SELECT * FROM(
    SELECT t.c_date, t.next_date, t.next_date - t.c_date as diff FROM(
     SELECT o.date as c_date, 
       lead(o.date) over (ORDER BY o.date ASC) AS next_date 
     FROM observation o 
     WHERE nr_id = '7810' and 
     date between '2012-01-01' and '2017-12-31') as t) as b 
WHERE diff > '6 days' 

回答

2

使用lead()

select o.date, (next_date - date) as diff 
from (select o.*, lead(date) over (order by date) as next_date 
     from observation o 
    ) o 
where next_date > date + interval '6 day'; 

的Postgres应该使用索引上observation(date)

您可以将where子句添加到子查询:

where nr_id = 7810 and 
     date between '2014-01-01' and '2014-12-31' 

我猜测nr_id是一个数字。如果您使用此版本,那么您需要observation(nr_id, date)上的索引。

+0

谢谢!好的解决方案 – dekarz