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

Posted

技术标签:

【中文标题】计算同一列中两个日期之间的日期【英文标题】:Counting dates that fall between two dates in the same column 【发布时间】:2013-08-02 07:20:21 【问题描述】:

我有两个表,对于表 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

【问题讨论】:

您是否尝试过laglead 函数来获取Time 的下一个/上一个值? 【参考方案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
;

【讨论】:

【参考方案2】:

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 joint1 必须有零计数。

【讨论】:

我相信应该可以正常工作,但刚刚发现我们使用 Amazon Redsfhit 并且不支持某些功能。对于前导函数,我收到错误消息“窗口函数前导不支持默认参数”并且 tsrange 函数不存在。我会尝试看看是否有解决方法。谢谢!

以上是关于计算同一列中两个日期之间的日期的主要内容,如果未能解决你的问题,请参考以下文章

Power BI 计算单个列中两个或多个日期之间的日期

两个不同列中日期之间的 SQL COUNT

C语言,使用结构体读入两个在同一年的日期,判断日期是否合法,并计算两个日期之间相差的天数。结构体定义如下:

计算同一表中一列中日期之间的差异

Pandas DataFrame 中两个日期之间的差异

从 2 个 REF 列中获取两个日期之间的差异