我下面有两个表-一个表的每个ID都有一行,以及特定事件发生的日期(如果尚未发生该事件,则为null);另一个表在每个日期的每一行都有一个行,其中每个ID的警告标志都标记为“ Y”,如果未标记该标志,则该ID和日期没有行:
(请注意英国日期格式)
ID Event Date
1 04/09/2018
2 null
3 05/09/2018
4 07/09/2018
ID Date Warning Flag
1 01/09/2018 Y
1 02/09/2018 Y
1 03/09/2018 Y
2 01/09/2018 Y
2 02/09/2018 Y
2 03/09/2018 Y
3 01/09/2018 Y
3 02/09/2018 Y
3 03/09/2018 Y
4 01/09/2018 Y
4 02/09/2018 Y
4 06/09/2018 Y
我想选择任何事件日期在事件日期前一天标记有警告标志的ID,以及警告标志字符串开始的日期。所以
ID First Warning Date
1 01/09/2018
4 06/09/2018
ID2没有活动日期; ID3在事件发生日期的前一天没有警告标志;和ID4有两个警告标志字符串,但仅应计算最近的字符串。
我什至不知道如何启动它,任何指针?
在尝试构建查询之前,您会重新排列任何表/构建汇总表吗?还是可以在单个查询中完成所有操作?
[这最终将由Oracle或HiveQL中的其他人编码,但我想在查询逻辑深入了解查询逻辑之前,因为他们无论如何都会问我:)]
答案 0 :(得分:1)
这是关于群体和岛屿问题的变体。您可以先将警告划分为多个范围。
请注意,日期算术特定于数据库,因此确切的语法因数据库而异。但这就是这个想法:
select min(date) as mindate, max(date) as maxdate
from (select df.*, row_number() over (partition by id order by date) as seqnum
from dailyflag df
) df
group by date - seqnum * interval '1 day';
接下来,将其用于join
,然后使用一些日期算术得出结果:
select e.*,
(e.event_date - df.mindate + 1) as numdays
from events e join
(select min(date) as mindate, max(date) as maxdate
from (select df.*, row_number() over (partition by id order by date) as seqnum
from dailyflag df
) df
group by date - seqnum * interval '1 day'
) df
on e.event_date - interval '1 day' between df.mindate and df.maxdate;
我必须强调,这本质上是伪代码,因为日期函数需要针对您使用的任何数据库进行自定义。