繁体   English   中英

Hive SQL-获取重叠日期的最小和最大日期

[英]Hive SQL - Getting Min and Max dates for Overlapping Dates

我有以下包含帐号和日期的数据集

Account     Start Date      End_Date
---------------------------------------
1111222333  05/01/2016      15/02/2016
1111222333  29/01/2016      04/04/2016
1111222333  20/03/2016      13/05/2016
1111222333  26/04/2016      06/06/2016
1111222333  05/05/2016      06/06/2016
1111222333  13/09/2016      10/10/2016
1111222333  14/10/2016      15/12/2016
1111222333  09/08/2017      25/08/2017
1111222333  25/10/2017      10/11/2017
1111222333  02/11/2017      05/01/2018

大多数日期范围是重叠的,因此我需要重叠范围中的最小开始日期和最大结束日期,因此输出应如下所示:

Account     Start Date   End_Date
----------------------------------
1111222333  05/01/2016  06/06/2016
1111222333  13/09/2016  10/10/2016
1111222333  14/10/2016  15/12/2016
1111222333  09/08/2017  25/08/2017
1111222333  25/10/2017  05/01/2018

我是一个新手用户,意识到以上内容远远超出了我目前的能力,因此请专家:)

这是一个孤岛问题。 解决该问题的一种方法是获取所有日期的列表,并跟踪适用于“记录”的数量。 然后,一些窗口函数和聚合解决了该问题。

with d as (
      select account, startdate as dte, 1 as inc
      from t
      union all
      select account, enddate as dte, -1 as inc
      from t
     ),
     ds as (  -- accumulate "inc".  Rows with "0" are ends of islands
      select account, dte, sum(running_inc) over (partition by account order by dte) as running_inc
      from (select account, dte, sum(inc) as running_inc
            from d
            group by account, dte
           ) d
     ),
     g as (  -- assign group
      select account, dte,
             sum(case when running_inc = 0 then 1 else 0 end) over (partition by account order by dte desc) as grp
      from ds
     )

select account, min(dte) as start_date, max(dte) as end_dte
from g
group by account, grp;

这是一个右撇子 (使用Postgres)。

这是上个月的代码:

with t(account, startdate, enddate) as (
      select 1111222333, '2016-01-05'::date, '2016-02-15'::date union all
      select 1111222333, '2016-01-29'::date, '2016-04-04'::date union all
      select 1111222333, '2016-03-20'::date, '2016-05-13'::date union all
      select 1111222333, '2016-04-26'::date, '2016-06-06'::date union all
      select 1111222333, '2016-05-05'::date, '2016-06-06'::date union all
      select 1111222333, '2016-09-13'::date, '2016-10-10'::date union all
      select 1111222333, '2016-10-14'::date, '2016-12-15'::date union all
      select 1111222333, '2017-08-09'::date, '2017-08-25'::date union all
      select 1111222333, '2017-10-25'::date, '2017-11-10'::date union all
      select 1111222333, '2017-11-02'::date, '2018-01-05'::date 
    ),
    d as (
      select account, startdate as dte, 1 as inc
      from t
      union all
      select account, enddate as dte, -1 as inc
      from t
     ),
     ds as (  -- accumulate "inc".  Rows with "0" are ends of islands
      select account, dte, sum(running_inc) over (partition by account order by dte) as running_inc
      from (select account, dte, sum(inc) as running_inc
            from d
            group by account, dte
           ) d
     ),
     g as (  -- assign group
      select account, dte,
             sum(case when running_inc = 0 then 1 else 0 end) over (partition by account order by dte desc) as grp
      from ds
     )
select account, min(dte) as start_date, max(dte) as end_dte
from g
group by account, grp;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM