2017-04-25 165 views
0

我有一張主表,其中所有結果都將寫入。 將被檢查由ITEM_ID確定每個對象:Postgres:將數據與以前的數據進行比較的查詢

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 

在Postgres的查詢我選擇用CURRENT_DATE所有結果=了checkdate提供的最新數據:

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

到目前爲止,它不是對我來說是一個問題。但是現在我想將這些結果與以前的結果進行比較。類似的東西:

Item Price Cat A Price Cat A Before Price Cat B Price Cat B Before 
1  29.99   39.99    84.99   89.99 
2  42.99   41.99    88.99   81.99 

但我不知道該怎麼做。這些項目每天不存在(例如,2017-04-24項目不存在)。

有人可以幫助我嗎?

+0

條件'current_date = checkdate'似乎意味着你每天檢查所有(當前)項目。是這樣嗎?聞起來有趣... – leonbloy

+0

有趣的是什麼?應用程序每天捕獲一次最新數據並將其存儲在數據庫中。上面的查詢將被webservices調用以獲取最新的數據(具有緩存功能)。 current_date在這裏是需要的,因爲有時(如上所述)項目不存在(但可能會再次存在)。 – user2622344

回答

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

您可以使用橫向聯接:

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

這些項目並非任何天存在 - 因爲這樣,你的原始查詢有錯誤太(即它贏得了」不包含你所有的物品)。

如果你正在尋找的最後一個(和倒數第二)checkdate,就沒有必要使用current_date(除非,有可能是你的表未來的數據;在這種情況下,只是追加where checkdate <= current_date將它們過濾出來)。

發現最後一排(其組,即你的情況,這是item_id內)是一個典型的問題,倒數第二是容易與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,這對我來說真的很複雜。你能解釋一下關鍵詞「窗口」,「分區依據」是什麼意思?此外,第一行(不同於(item_id))? – user2622344

+0

@ user2622344這些是[窗口函數](https://www.postgresql.org/docs/current/static/tutorial-window.html)調用的一部分。在鏈接的資源中詳細瞭解它們。 – pozs

相關問題