我希望这个问题没问题。我不知道在SO或Google上搜索什么,以找到可能的解决方案。
我正在使用PostgreSQL 9.3。
我从各种停车收费表中获得了停车票交易的大量数据。 所有记录都包含timestamp_begin,timestamp_end和parking_meter_id单元格。
如果我想查看停车收费表的当前活动门票,我只计算NOW()在timestamp_begin和timestamp_end之间以及按parking_id分组的门票。
但是如果我想知道当前活跃的门票是否高于或低于历史数据的某种平均最大值,例如上个月呢?
我希望能够显示是否有可能在某个停车收费表附近找到一个免费停车位,基于它与历史数据相比的活动。
我应该如何应对这样的挑战?我迷失了想法......
答案 0 :(得分:2)
您可以使用case
轻松比较当前和上个月。 (请注意,Now()
现在可以在我的计算机上运行,但您可能会有不同的时间并获得不同的结果。)
-- drop table if exists parking;
create table parking
(timestamp_begin timestamp,
timestamp_end timestamp,
parking_meter_id integer);
insert into parking values
('2014-05-25 12:01','2014-05-25 13:00',1),
('2014-05-25 12:02','2014-05-25 14:00',1),
('2014-05-25 12:03','2014-05-25 15:00',2),
('2014-05-25 12:04','2014-05-25 16:00',2),
('2014-06-25 12:30','2014-06-25 16:00',1),
('2014-06-25 12:31','2014-06-25 16:00',1),
('2014-06-25 12:32','2014-06-25 16:00',2),
('2014-06-25 12:30','2014-06-25 16:00',2),
('2014-06-25 12:34','2014-06-25 16:00',3),
('2014-06-25 12:30','2014-06-25 16:00',3);
select
parking_meter_id,
sum(case when Now() between timestamp_begin and timestamp_end
then 1 else 0 end) as current_data,
sum(case when Now() - interval '1 month' between timestamp_begin and timestamp_end
then 1 else 0 end) as prev_month_data
from
parking
group by
parking_meter_id
order by
parking_meter_id
;
结果
parking_meter_id current_data prev_month_data
1 2 0
2 2 2
3 2 0
答案 1 :(得分:1)
我将回答问题1:如何获得与之比较的平均值。我和Tomas Greif在一起;你应该在“某个停车收费表附近”制作“免费停车位”。另外请求。
首先:做一个比较好的规则。周六,周日或周一的停车位将有所不同。所以你可能想要比较同一个工作日和时间。 (仍然有一天可能是假期,所以这种方法仍然不是很好)。假设我们想回顾三个月。首先获取我们认为适合比较的每一天的活动门票数量,然后获得所有这些天的平均值。
select avg(cnt) -- avarage number of active tickets on the compared days
from
(
select count(*) as cnt -- number of active tickets per day (as we group by day)
from tickets
where parking_id = 100
and timestamp_begin >= now() - interval '3 month' -- last three months
and to_char(timestamp_begin,'YYYYMMDD') < to_char(now(),'YYYYMMDD') -- but not today
and to_char(timestamp_begin,'D') = to_char(now(),'D') -- same weekday
and to_char(now(),'HH24MISS') between to_char(timestamp_begin,'HH24MISS') and to_char(timestamp_end,'HH24MISS') -- same time
group by to_char(timestamp_begin,'YYYYMMDD') -- group by day
) other_days;
概念中可能存在拼写错误或甚至是小错误,但您明白了这一点。