我有一个主表,我的所有结果都将被写入。 将检查的每个对象由item_id标识:
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
但我不知道该怎么做。这些项目并不是每天都存在(例如,第2项并不存在于2017-04-24)。
有人可以帮助我吗?
答案 0 :(得分: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
答案 1 :(得分: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;
答案 2 :(得分:0)
这些项目并非每天都存在 - 因此,您的原始查询也有错误(即它不会包含您的所有项目)。
如果您要查找最后一个(和最后一个)checkdate
,则无需使用current_date
(除非您的表中可能有未来数据;在这种情况下只需追加where checkdate <= current_date
过滤掉它们。)
查找最后一行(在其组中,即在您的情况下,它是item_id
)是典型的Azure's Table storage.问题,而使用greatest-n-per-group的第二行很容易:
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