2017-09-05 6 views
0

J'essaie de trouver les lacunes dans les données générées en même temps.Optimiser la requête SQL (trouver des lacunes dans les données) Postgresql

tableau simplifié ressemble à ceci:

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

Le résultat de la requête devrait ressembler à ceci:

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

2017-01-03 l'écart durant 27 jours a commencé.

J'ai écrit une telle requête et cela fonctionne. Cependant, cela prend beaucoup de temps sur un jeu de données plus volumineux (environ 20k lignes).

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' 

Est-ce que quelqu'un a une autre idée, comment l'écrire plus efficacement?

RÉPONSE (approche modifiée envoyée par 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' 

Répondre

2

Utilisation 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 devrait utiliser un index sur observation(date).

Vous pouvez ajouter la clause where à la sous-requête:

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

Je devine que nr_id est un nombre. Si vous utilisez cette version, vous voulez un index sur observation(nr_id, date).

+0

Merci! Excellente solution – dekarz