SQL在特定日期运行总和

时间:2015-02-17 10:57:25

标签: sql postgresql

我们假设这个表:

Dpt ctd dte
A   1   2014-01-06
A   2   2014-01-07
A   1   2014-01-07
B   1   2014-01-06
B   1   2014-01-07
A   2   2014-01-09
B   1   2014-01-10
A   1   2014-01-11
B   1   2014-01-13
A   2   2014-01-13

我想计算每个星期天的运行总和:

A   1   2014-01-06
B   1   2014-01-06
A   9   2014-01-13
B   4   2014-01-13

如何使用SQL查询执行此操作?运行PostgreSQL 9.3

4 个答案:

答案 0 :(得分:1)

使用SUM OVER获得总计。由于dpt每天可以有多个记录,因此必须先按dpt和day分组,然后在SUM(ctd)上运行总计。之后删除非星期天的日子。

select *
from
(
  select dpt, dte, sum(sum(ctd)) over (partition by dpt order by dte) as total
  from mytable
  group by dpt, dte
) distinct_days
where to_char(dte,'D') = '1' -- Sunday is '1', Monday is '2', etc.
order by dte, dpt;

(您可以通过首先在所有记录上使用SUM OVER并使用DISTINCT删除结果中的重复项来实现相同目的。但是,对我来说,首先分组感觉更自然。)

答案 1 :(得分:0)

以下是我们如何在Oracle中实现这一目标。我很确定使用PostgreSQL也可以做到这一点。我想,2014-01-06和2014-01-13是星期一。

with data_ as (select dpt, ctd, to_date(dte,'yyyy-mm-dd') dte from
(select 'A' dpt, 1 ctd, '2014-01-06' dte from dual
union all
select 'A' ,2 , '2014-01-07' from dual
union all
select 'A' ,1 , '2014-01-07' from dual
union all
select 'B' ,1 , '2014-01-06' from dual
union all
select 'B' ,1 , '2014-01-07' from dual
union all
select 'A' ,2 , '2014-01-09' from dual
union all
select 'B' ,1 , '2014-01-10' from dual
union all
select 'A' ,1 , '2014-01-11' from dual
union all
select 'B' ,1 , '2014-01-13' from dual
union all
select 'A' ,2 , '2014-01-13' from dual))


select dpt, dte, ord runn_sum
from (select dpt, dte, trim(both from to_char(dte,'Day')) day_,
sum(ctd) over (partition by dpt order by dte) ord
from data_) where day_ = 'Monday'
order by 2 asc;

答案 2 :(得分:0)

with t (dpt, ctd, dte) as (
    values
        ('a', 1, '2014-01-06'::date),
        ('a', 2, '2014-01-07'),
        ('a', 1, '2014-01-07'),
        ('b', 1, '2014-01-06'),
        ('b', 1, '2014-01-07'),
        ('a', 2, '2014-01-09'),
        ('b', 1, '2014-01-10'),
        ('a', 1, '2014-01-11'),
        ('b', 1, '2014-01-13'),
        ('a', 2, '2014-01-13')
)
select dte, dpt, total
from (
    select
        dte, dpt,
        sum(ctd) over(partition by dpt order by dte) as total
    from t
) s
where extract(isodow from dte) = 1
order by dte, dpt
;
    dte     | dpt | total 
------------+-----+-------
 2014-01-06 | a   |     1
 2014-01-06 | b   |     1
 2014-01-13 | a   |     9
 2014-01-13 | b   |     4

答案 3 :(得分:0)

这不要求在星期日有条目(它确实适用于星期日,而不是星期一):

with t (dpt, ctd, dte) as (
  values ('a', 2, date '2014-01-05'),
     ('a', 1, '2014-01-06'),
     ('a', 2, '2014-01-07'),
     ('a', 1, '2014-01-07'),
     ('b', 1, '2014-01-06'),
     ('b', 1, '2014-01-07'),
     ('a', 2, '2014-01-09'),
     ('b', 1, '2014-01-10'),
     ('a', 1, '2014-01-11'),
     ('b', 1, '2014-01-13'),
     ('a', 2, '2014-01-13')
)
select dpt, monday + 6 sunday,
       sum(ctd_sum) over(partition by dpt order by monday) total
from (
  select dpt, date(date_trunc('week', dte)) monday, sum(ctd) ctd_sum
  from   t
  group by 1, 2
) sub;

 dpt |    dte     | total 
-----+------------+-------
 a   | 2014-01-05 |     2 
 a   | 2014-01-12 |     9 
 a   | 2014-01-19 |    11 
 b   | 2014-01-12 |     3 
 b   | 2014-01-19 |     4