2

我有两个表,对于表 1 中的每个 ID 和级别组合,我需要在表 1 中的级别的连续时间之间计算匹配 ID 出现在表 2 中的次数。

例如,对于 table1 中的 ID = 1 和 Level=1,来自 table2 的两个 ID=1 的时间条目落在 table1 中 Level=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
4

2 回答 2

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
;
于 2014-04-20T08:01:29.527 回答
-1

SQL小提琴

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。这意味着包括下限并排除上限。

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

t1必须left join有零计数。

于 2013-08-02T12:25:55.493 回答