优化 SQL 查询(查找数据中的差距)Postgresql
Optimise SQL query (finding gaps in data) Postgresql
我试图找出同时生成的数据中的差距。
简化后的 table 看起来像这样:
--------------------
| 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'
有没有人有任何其他想法,如何更有效地编写它?
答案(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'
使用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)
.
上的索引
我试图找出同时生成的数据中的差距。
简化后的 table 看起来像这样:
--------------------
| 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'
有没有人有任何其他想法,如何更有效地编写它?
答案(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'
使用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)
.