Postgres:查询将数据与以前的数据进行比较

时间:2017-04-25 12:50:00

标签: postgresql aggregate

我有一个主表,我的所有结果都将被写入。 将检查的每个对象由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)。

有人可以帮助我吗?

3 个答案:

答案 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.问题,而使用的第二行很容易:

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

lag() window function