计算同一列中两个日期之间的日期

时间:2013-08-02 07:20:21

标签: amazon-redshift

我有两个表,对于table1中的每个ID和Level组合,我需要在table1中的级别的连续时间之间获得匹配ID的次数。

因此,例如,对于table1中的ID = 1和Level = 1,来自table2的ID = 1的两个Time条目落在table1中的Level of 1和Level = 2之间,因此结果表中的结果将为2 。

table1:

ID  Level   Time
1   1   6/7/13 7:03
1   2   6/9/13 7:05
1   3   6/12/13 12:02
1   4   6/17/13 5:01
2   1   6/18/13 8:38
2   3   6/20/13 9:38
2   4   6/23/13 10:38
2   5   6/28/13 1:38

table2:

ID  Time
1   6/7/13 11:51
1   6/7/13 14:15
1   6/9/13 16:39
1   6/9/13 19:03
2   6/20/13 11:02
2   6/20/13 15:50

结果将是

ID  Level   Count
1   1   2
1   2   2
1   3   0
1   4   0
2   1   0
2   3   2
2   4   0
2   5   0

2 个答案:

答案 0 :(得分:1)

select transformed_tab1.id, transformed_tab1.level, count(tab2.id)
from
(select tab1.id, tab1.level, tm, lead(tm) over (partition by id order by tm) as next_tm
from
(
select 1 as id, 1 as level, '2013-06-07 07:03'::timestamp as tm union
select 1 as id, 2 as level, '2013-06-09 07:05 '::timestamp as tm union
select 1 as id, 3 as level, '2013-06-12 12:02'::timestamp as tm union
select 1 as id, 4 as level, '2013-06-17 05:01'::timestamp as tm union
select 2 as id, 1 as level, '2013-06-18 08:38'::timestamp as tm union
select 2 as id, 3 as level, '2013-06-20 09:38'::timestamp as tm union
select 2 as id, 4 as level, '2013-06-23 10:38'::timestamp as tm union
select 2 as id, 5 as level, '2013-06-28 01:38'::timestamp as tm) tab1
) transformed_tab1
left join
(select 1 as id, '2013-06-07 11:51'::timestamp as tm union
select 1 as id, '2013-06-07 14:15'::timestamp as tm union
select 1 as id, '2013-06-09 16:39'::timestamp as tm union
select 1 as id, '2013-06-09 19:03'::timestamp as tm union
select 2 as id, '2013-06-20 11:02'::timestamp as tm union
select 2 as id, '2013-06-20 15:50'::timestamp as tm) tab2
on transformed_tab1.id=tab2.id and tab2.tm between transformed_tab1.tm and transformed_tab1.next_tm
group by transformed_tab1.id, transformed_tab1.level
order by transformed_tab1.id, transformed_tab1.level
;

答案 1 :(得分:-1)

SQL Fiddle

select t1.id, level, count(t2.id)
from
    (
        select id, level,
            tsrange(
                "time",
                lead("time", 1, 'infinity') over(
                    partition by id order by level
                    ),
                '[)'
            ) as time_range
        from t1
    ) t1
    left join
    t2 on t1.id = t2.id and t1.time_range @> t2."time"
group by t1.id, level
order by t1.id, level

解决方案使用lead窗口函数开始创建一系列时间戳。注意[)构造函数的tsrange参数。它意味着包括较低的并排除上限。

然后它使用@>范围运算符连接两个表。这意味着范围包括元素。

left join t1必须具有零计数。