2017-04-25 9 views
0

Ich habe eine Haupttabelle, in die alle meine Ergebnisse geschrieben werden. Jedes Objekt, das identifiziert wird durch die item_id werden geprüft wird:Postgres: Abfrage zum Vergleichen von Daten mit früheren Daten

Checkdate  item_id Price Cat A Price Cat B 
2017-04-25 1   29.99   84.99 
2017-04-24 1   39.99   89.99 
2017-04-23 1   39.99   91.99 
2017-04-25 2   42.99   88.99 
2017-04-23 2   41.99   81.99 
2017-04-22 2   50.99   81.99 
2017-04-21 2   42.99   81.99 

In der Abfrage Postgres i alle Ergebnisse mit dem current_date select = checkdate die neuesten Daten zur Verfügung zu stellen:

Item Price Cat A  Price Cat B 
1  29.99   84.99 
2  42.99   88.99 

seine bisher nicht ein Problem für mich. Aber jetzt möchte ich diese Ergebnisse mit den vorherigen Ergebnissen vergleichen. Etwas wie das:

Aber ich habe keine Idee, wie man das macht. Diese Artikel sind nicht an jedem Tag vorhanden (Artikel 2 existiert zum Beispiel am 24.04.2017 nicht).

Kann mir jemand helfen?

+0

Die Bedingung 'current_date = checkdate' scheint zu implizieren, dass Sie alle Ihre (aktuellen) Elemente jeden Tag überprüfen. Ist das so? Riecht komisch ... – leonbloy

+0

Was ist daran lustig? Die Anwendung fängt die neuesten Daten einmal täglich ab und speichert diese in einer Datenbank. Die obige Abfrage wird von webservices aufgerufen, um die neuesten Daten (mit einer Caching-Funktionalität) zu erhalten. current_date wird hier benötigt, weil manchmal (wie erwähnt) Elemente nicht existieren (aber vielleicht morgen wieder existiert). – user2622344

Antwort

0
select 
    item_id, 
    min(price_cat_a) filter (where rn = 1) as a, 
    min(price_cat_a) filter (where rn = 2) as a_before, 
    min(price_cat_b) filter (where rn = 1) as b, 
    min(price_cat_b) filter (where rn = 2) as b_before 
from (
    select 
     item_id, price_cat_a, price_cat_b, 
     row_number() over (partition by item_id order by checkdate desc) as rn 
    from t 
    where checkdate <= current_date 
) s 
where rn <= 2 
group by item_id 
; 
item_id | a | a_before | b | b_before 
---------+-------+----------+-------+---------- 
     1 | 29.99 | 39.99 | 84.99 | 89.99 
     2 | 42.99 | 41.99 | 88.99 | 81.99 
0

Sie können eine seitliche verwenden beitreten:

SELECT today.item_id, 
     today."Price Cat A", 
     before."Price Cat A" AS "Price Cat A Before", 
     today."Price Cat B", 
     before."Price Cat B" AS "Price Cat B Before" 
FROM main today 
    CROSS JOIN LATERAL 
    (SELECT "Price Cat A", 
      "Price Cat B" 
     FROM main 
     WHERE item_id = today.item_id 
     AND "Checkdate" < today."Checkdate" 
     ORDER BY "Checkdate" DESC 
     LIMIT 1 
    ) before 
WHERE today."Checkdate" = current_date 
ORDER BY today.item_id; 
0

Diese Elemente existiert nicht an jedem Tag - aus diesem Grund, Ihre ursprüngliche Anfrage zu einen Fehler hat (dh es hat‘ t enthalten alle Ihre Artikel).

Wenn Sie die letzte (und vorletzten) checkdate, da suchen, ist keine Notwendigkeit current_date zu verwenden (es sei denn, es könnte in der Tabelle zukünftige Daten sein, in diesem Fall where checkdate <= current_date nur hängen Sie sie heraus zu filtern).

die letzte Zeile zu finden (innerhalb ihrer Gruppe, in Ihrem Fall, dh, es ist item_id) ist ein typisches Problem, und die zweite letzte ist einfach, mit der lag() window function:

select distinct on (item_id) 
     item_id, 
     price_cat_a, 
     price_cat_a_before, 
     price_cat_b, 
     price_cat_b_before 
from  (select *, 
       lag(price_cat_a) over w price_cat_a_before, 
       lag(price_cat_b) over w price_cat_b_before 
      from t 
      window w as (partition by item_id order by checkdate)) t 
order by item_id, checkdate desc 

http://rextester.com/AGZ99646

+0

Puuh, das ist wirklich kompliziert für mich. Kannst du erklären, was die Schlüsselwörter "window", "partition by" bedeuten? Und außerdem die erste Zeile (distinct on (item_id))? – user2622344

+0

@ user2622344 Diese sind Teile eines [Fensterfunktion] (https://www.postgresql.org/docs/current/static/tutorial-window.html) Anrufs. Lesen Sie mehr über sie in den verlinkten Ressourcen. – pozs

Verwandte Themen