每周从postgres获取数据(根据日期)

时间:2015-10-07 11:35:44

标签: postgresql date

user  timespent(in sec)  date(in timestamp)
u1       10                t1(2015-08-15)
u1       20                t2(2015-08-19)
u1       15                t3(2015-08-28)
u1       16                t4(2015-09-06)

以上是我的表的格式,它表示用户在课程上的时间,并按时间戳排序。我希望获得特定用户的时间总和,例如每周u1格式:

start_date    end_date       sum
2015-08-15   2015-08-21      30
2015-08-22   2015-08-28      15
2015-08-29   2015-09-04      0
2015-09-05   2015-09-11      16

3 个答案:

答案 0 :(得分:1)

困难在于,您想要获得的七天时间段不是从周一开始的常规周。 因此,您无法使用标准函数根据日期获取周数,并且必须使用generate_series()使用您自己的周生成器

示例数据:

create table sessions (user_name text, time_spent int, session_date timestamp);
insert into sessions values
('u1', 10, '2015-08-15'),
('u1', 20, '2015-08-19'),
('u1', 15, '2015-08-28'),
('u1', 16, '2015-09-06');

2015-08-15至2015-09-06之间任意选定期间的查询:

with weeks as (
    select d::date start_date, d::date+ 6 end_date
    from generate_series('2015-08-15', '2015-09-06', '7d'::interval) d
    )
select w.start_date, w.end_date, coalesce(sum(time_spent), 0) total
from weeks w
left join (
    select start_date, end_date, coalesce(time_spent, 0) time_spent
    from weeks
    join sessions
    on session_date between start_date and end_date
    where user_name = 'u1'
    ) s
on w.start_date = s.start_date and w.end_date = s.end_date
group by 1, 2
order by 1;

 start_date |  end_date  | total
------------+------------+-------
 2015-08-15 | 2015-08-21 |    30
 2015-08-22 | 2015-08-28 |    15
 2015-08-29 | 2015-09-04 |     0
 2015-09-05 | 2015-09-11 |    16
(4 rows)

答案 1 :(得分:0)

这样的事情(假设您通过时间戳表示数据类型timestamp)。 为了使一周的第一天成为星期日,我添加了额外的一天,以及#34; date"在group by

select (start_date - date_part('dow', start_date) * interval '1 day')::date start_date,
       (start_date + (6 - date_part('dow', start_date)) * interval '1 day')::date end_date,
        total_time_spent
from (
    select min("date") start_date, sum(timespent) total_time_spent
    from mytable
    where user=u1
    group by date_part('year', "date"), date_part('week', "date" + interval '1 day')) "tmp"

order by start_date

对于任何日期间隔,这是一种更通用的方法。

答案 2 :(得分:0)

select
    ui,
    date_trunc('week', the_date)::date as start_date,
    date_trunc('week', the_date)::date + 6 as end_date,
    sum(timespent) as "sum"
from t
group by 1, 2, 3
order by 1,2