我正在尝试使用PostgreSQL将当前月份数据的值与前几个月进行比较。因此,如果今天是4/23/2018,我想要3/23/2018的数据。
我已经尝试了current_date - interval '1 month'
但是这个问题持续了31个月。
我的表格结构简单
日期,价值
答案 0 :(得分:0)
检查此示例查询:
WITH dates AS (SELECT date::date FROM generate_series('2018-01-01'::date, '2018-12-31'::date, INTERVAL '1 day') AS date)
SELECT
start_dates.date AS start_date,
end_dates.date AS end_date
FROM
dates AS start_dates
RIGHT JOIN dates AS end_dates
ON ( start_dates.date + interval '1 month' = end_dates.date AND
end_dates.date - interval '1 month' = start_dates.date);
它会输出所有end_dates
和相应的start_dates
。相应的日期由interval '1 month'
定义,并以两种方式进行检查:
start_dates.date + interval '1 month' = end_dates.date AND
end_dates.date - interval '1 month' = start_dates.date
输出如下:
....
2018-02-26 2018-03-26
2018-02-27 2018-03-27
2018-02-28 2018-03-28
2018-03-29
2018-03-30
2018-03-31
2018-03-01 2018-04-01
2018-03-02 2018-04-02
2018-03-03 2018-04-03
2018-03-04 2018-04-04
....
请注意,存在“差距”。没有相应日期的日子。
回到你的表,自己加入表(给出别名)并使用给定的连接条件,所以查询看起来像这样:
SELECT
start_dates.value - end_dates.value AS change,
start_dates.date AS start_date,
end_dates.date AS end_date
FROM
_your_table_name_ AS start_dates
RIGHT JOIN _your_table_name_ AS end_dates
ON ( start_dates.date + interval '1 month' = end_dates.date AND
end_dates.date - interval '1 month' = start_dates.date);
答案 1 :(得分:0)
给出以下表结构:
create table t (
d date,
v int
);
在填充了一些日期和值之后,有一种方法可以使用简单的计算和LAG函数来查找上个月的值,而无需求助于连接。从性能的角度来看,我不确定该如何进行比较,因此请先运行自己的测试,然后再选择要使用的解决方案。
select
*,
lag(v, day_of_month) over (order by d) as v_end_of_last_month,
lag(v, last_day_of_previous_month + day_of_month - cast(extract(day from d - interval '1 month') as int)) over (order by d) as v_same_day_last_month
from (
select
*,
lag(day_of_month, day_of_month) over (order by d) as last_day_of_previous_month
from (
select
*,
cast(extract(day from d) as int) as day_of_month
from
t
) t_dom
) t_dom_ldopm;
您可能会注意到,在3月29日至31日之间,将与2月28日进行比较,因为在那个特定日期,2月不存在同一天。相同的逻辑适用于其他天数不同的月份。