合并各自的开始和结束日期,根据 Start/End 日期设置标志 - SQL

Merging Respective Start and End Dates, Setting Flag Depending on Start/End Date - SQL

问题: 我有一个 table 的交易(见下文),其中有 (open/start) 或 (close/end) 日期格式的交易。任务是将这些交易与其相应的日期合并,但是,也可能存在交易为 opened/started 而不是 closed/ended 的情况,在这种情况下,只需要显示开始日期,并且标记'Y' 已分配。在有结束日期的其他情况下,标志将为 'N'。我已经能够根据 first_value(Flag IGNORE NULLS) over(partition by Customer_ID order by EndDate desc) 的值设置一个标志,但是我在匹配开始时遇到了一些困难结束日期。

逻辑:

当前设置示例如下所示: 注意:对于这个特定的客户,我们有相同数量的交易(插入和删除,所以我知道标志将是 'N',当我们映射开始和结束日期时,但解决方案也必须在开始日期多于其他客户的结束日期,其中最终(最新)开始日期行的标志为 'Y'.

Customer_Id Start Date End Date Flag
111 02/07/2020 20:58:32.000000 N
111 02/07/2020 19:18:04.000000 N
111 01/06/2020 09:38:49.000000 N
111 01/06/2020 09:36:34.000000 N
111 29/05/2020 16:58:07.000000 N
111 02/07/2020 20:57:52.000000 N
111 02/07/2020 19:17:22.000000 N
111 29/05/2020 16:58:06.000000 N
111 01/06/2020 09:38:40.000000 N
111 01/06/2020 09:36:34.000000 N

预期结果:

Customer_Id Start Date End Date Flag
111 02/07/2020 20:57:52.000000 02/07/2020 20:58:32.000000 N
111 02/07/2020 19:17:22.000000 02/07/2020 19:18:04.000000 N
111 01/06/2020 09:38:40.000000 01/06/2020 09:38:49.000000 N
111 01/06/2020 09:36:34.00000 01/06/2020 09:36:34.000000 N
111 29/05/2020 16:58:06.000000 29/05/2020 16:58:07.000000 N

适用于上述示例的部分解决方案:

select customer_id
  ,start_date
  ,lead(end_date) -- find the next row's end date
   over (partition by customer_id
         order by coalesce(start_date, end_date)) as new_end
  ,case when new_end is null then 'Y' else 'N' end as flag
from tab
qualify start_date is not null -- only return starting rows
order by 1,2;

但是,如果开始日期多于结束日期(例如,几个关闭的交易,一个打开(不仅可以是 latest/newest 一个,也可以是中间的某个地方..))不行。例如。如果交易开放:开始日期 12/01/2019 09:36:34.00000 但没有结束日期 然后 lead() 跳过这个空结束日期值并分配下一个可用的结束日期,使解决方案看起来像这样:

Customer_Id Start Date End Date Flag
111 02/07/2020 20:57:52.000000 02/07/2020 20:58:32.000000 N
111 02/07/2020 19:17:22.000000 02/07/2020 19:18:04.000000 N
111 01/06/2020 09:38:40.000000 01/06/2020 09:38:49.000000 N
111 12/01/2019 09:36:34.00000 18/11/2019 16:58:07.000000 N
111 18/11/2019 16:58:06.000000 NULL NULL

什么时候应该是这样的:

Customer_Id Start Date End Date Flag
111 02/07/2020 20:57:52.000000 02/07/2020 20:58:32.000000 N
111 02/07/2020 19:17:22.000000 02/07/2020 19:18:04.000000 N
111 01/06/2020 09:38:40.000000 01/06/2020 09:38:49.000000 N
111 12/01/2019 09:36:34.00000 NULL Y
111 18/11/2019 16:58:06.000000 18/11/2019 16:58:07.000000 N

如何找到适合这两种情况的解决方案?

这将 return 每个开始日期的匹配结束日期。

select customer_id
  ,start_date
  ,lead(end_date) -- find the next row's end date
   over (partition by customer_id
         order by coalesce(start_date, end_date)) as new_end
  ,case when new_end is null then 'Y' else 'N' end as flag
from tab
qualify start_date is not null -- only return starting rows
order by 1,2;