postgreSQL选择昨天的值,月平均值
我有一个PostgreSQL表:postgreSQL选择昨天的值,月平均值,sql,postgresql,Sql,Postgresql,我有一个PostgreSQL表: create table UV( f_date int, uv bigint ) 数据: 那么,如何使用sql生成这样的表: f_date | uv_today | uv_yesterday | uv_month_avg ---------+------------+--------------+-------------- 20150103 | 620964 |(uv of 20150102)| average uv from 201412
create table UV(
f_date int,
uv bigint
)
数据:
那么,如何使用sql生成这样的表:
f_date | uv_today | uv_yesterday | uv_month_avg
---------+------------+--------------+--------------
20150103 | 620964 |(uv of 20150102)| average uv from 20141204 to 20150103
20150104 | 595367 | 620964 |
我会选择选择列表中的子选择:
select f_date,
uv as uv_today,
(select uv from uv as u2
where u2.f_date = uv.f_fdate - 1) as uv_yesterday,
(select avg(uv) from uv as u2
where u2.f_date between uv.f_fdate - 30 and uv.f_fdate) as uv_month_avg
from uv
请注意,我不想正确计算负1个月,因为我不知道在postgresql中如何计算,只需要-30天。首先:不要将日期存储为整数!如果您想要日期,请使用date
!尤其不要将日期存储为整数,位置值用于表示年、月和日。认真地在继续实际使用该模式之前,需要先修复该模式。将历元值存储为朱利安日期,或使用本机数据类型日期
、时间戳
和间隔
进行正确的日期/时间工作
第一部分是一个窗口函数的简单应用;只需延迟(uv,1)超过(按f_日期订购)
第二种方法有点棘手,但是一旦你修复了你的模式,它就不会太糟糕了。假设您想要一个日历月,您可以在(按日期划分(“月”,f_日期))上使用avg(uv)
。如果你想要30天的间隔,那是另一回事
比如:
create table UV(
f_date date,
uv bigint
);
insert into UV (f_date, uv)
VALUES ('20150103', '620964'),
('20150104', '595367');
SELECT
f_date,
uv,
lag(uv, 1) OVER (ORDER BY f_date),
avg(uv) OVER (PARTITION BY date_trunc('month', f_date))
FROM UV;
如图所示:
-interval'1'month
@CraigRinger,即使将日期存储为int?我只是在发表评论后才注意到。在这种情况下,正确的做法是不将日期存储为int,因为这太可怕了。或者强制转换它或其他什么。稍微少于绝对最小的样本数据是有用的,尽管这肯定比没有好。为什么要使用bigint作为日期?您应该将日期存储在date
列中。我将尝试修复我的模式。
create table UV(
f_date date,
uv bigint
);
insert into UV (f_date, uv)
VALUES ('20150103', '620964'),
('20150104', '595367');
SELECT
f_date,
uv,
lag(uv, 1) OVER (ORDER BY f_date),
avg(uv) OVER (PARTITION BY date_trunc('month', f_date))
FROM UV;