结束”

tuwxkamq  于 2021-06-26  发布在  Impala
关注(0)|答案(2)|浏览(254)

我在一个有几个日期的表中重复了行:

ID      STATE       DATE
----------------------------
id01   connected  2015-04-04
id01   connected  2015-04-05
id01   connected  2015-04-08
id01   disconect  2015-04-11
id01   disconect  2015-04-12
id01   connected  2015-04-13

我想要一个带有“开始日期”和“结束日期”的查询,结果如下:

ID      STATE    START DATE   END DATE
----------------------------------------
id01   connected  2015-04-04  2015-04-10
id01   disconect  2015-04-11  2015-04-12
id01   connected  2015-04-13  XXXXXXXXXX

最后一个“结束日期”并不重要(last value,null,now()…)
最重要的是检测更改日期(在本例中,2015-04-10没有行,相同的状态发生在2015-04-13)。
可行的解决方案((无效)

SELECT ID, STATE, MIN(date), MAX(date) 
   FROM TABLE
   GROUP BY ID, STATE;

无效,因为合并间隔:

ID      STATE    START DATE   END DATE
----------------------------------------
id01   connected  2015-04-04  XXXXXXXXXX
id01   disconect  2015-04-11  2015-04-12

查询已在impala中运行(类似于sql92)

7uzetpgm

7uzetpgm1#

impala支持窗口功能。这个问题是一个“间隙和孤岛”问题,因此可以使用行号差来解决:

select id, state, min(date) as start_date, max(date) as end_date
from (select t.*,
             row_number() over (partition by id order by date) as seqnum_id,
             row_number() over (partition by id, state order by date) as seqnum_isd
      from table t
     ) t
group by id, state, (seqnum_id - seqnum_isd);

这种差异的逻辑并不难,但当你第一次学习它的时候就很棘手了。它有助于运行子查询并查看行号值是什么,以及为什么差异定义了每个组。

yruzcnhs

yruzcnhs2#

(代表op发布)。
从gordon linoff的回答,将“差距和岛屿”问题转化为我的研究案例,有一个解决方案:

select 
    id,
    state,
    start_date,
    date_add(lag(start_date, 1) over (partition by id order by start_date desc), -1) as end_date
from 
    (select id, state, min(date) as start_date, max(date) as end_date
        from (select t.*,
                row_number() over (partition by id order by date) as seqnum_id,
                row_number() over (partition by id, state order by date) as seqnum_isd
            from test t
        ) t
    group by id, state, (seqnum_id - seqnum_isd)) t_range
order by start_date;

相关问题