优化SQL查询(查找数据中的空白)Postgresql

时间:2017-09-05 10:57:02

标签: sql postgresql gaps-and-islands

我试图找到同时生成的数据的差距。

简化表如下所示:

--------------------
| 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-01-03持续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(Gordon Linoff发送的修改方法):

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'

1 个答案:

答案 0 :(得分: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)上的索引。