检查日期分割周期是否连续(并找出差距)

Check date split periods are continuous (and spotting the gaps)

我正在努力解决与此线程中类似的问题: Check date split periods are continuous

谁能帮我把 Qsebas 的答案翻译成 Presto 语言?因为这正是我想要实现的。

我不确定这部分的结果应该是什么:

CROSS APPLY  Enumerate ( ABS(DATEDIFF(d, From_Date, To_Date))) AS NUMBERS

以及如何替换它。将 ROW_NUMBER () 作为一列,将 ABS(DATE_DIFF()) 作为第二列吗?

我的示例数据:

license_plate create_timestamp delete_timestamp
AA-AAA 2019-10-08 10:47:54 \N
AA-AAA 2021-01-22 12:37:21 2021-07-21 8:27:44
AA-AAA 2021-07-19 9:10:39 \N
BB-BBB 2016-04-15 8:38:59 2021-11-04 10:51:18
BB-BBB 2018-03-13 13:56:39 2021-10-07 08:21:07
BB-BBB 2021-12-23 12:42:31 \N
CC-CCC 2019-07-26 21:22:42 2021-12-17 18:21:37
CC-CCC 2021-11-05 11:08:13 2022-02-11 08:44:22

我想得到这样的东西:

license_plate create_timestamp delete_timestamp
AA-AAA 2019-10-08 10:47:54 \N
BB-BBB 2016-04-15 8:38:59 2021-10-07 08:21:07
BB-BBB 2021-12-23 12:42:31 \N
CC-CCC 2019-07-26 21:22:42 2022-02-11 08:44:22

还可以有一列 count_ranges 来计算每个车牌有多少个范围。 每个车牌可以有很多条目,它们可以重叠(因此按 create_timestamp 排序并逐行比较不起作用)。 这个想法是将车辆(车牌)分组为:

我知道可能会有更多的场景(即 'Reactivated - Deleted'、'Reactivated - Reactivated',但现在这种拆分就可以了。

如果我有 table 我想要的,我可以通过以下方式将它们分配给组:

CASE WHEN count_ranges > 1 THEN 'Reactivated'
           WHEN count_ranges = 1 AND delete_timestamp is null THEN 'Active'
           WHEN count_ranges = 1 AND delete_timestamp is not null THEN 'Deleted'
END AS vehicle_status

也许有不同的方法可以做到这一点?

PS。在范围末尾列出确切的 delete_timestamp 并在下一个范围的开头列出单个车牌的确切 delete_timestamp 将有助于检查车牌是否被同一用户或某人重新激活否则。

谢谢!

使用链接答案中的示例数据,我建议使用间隙和孤岛方法 - 使用 lag 将之前的 to_date 与当前的 from_date 进行比较,然后将结果用于滚动总和形成分组:

-- sample data
WITH dataset (ref, from_date, to_date) AS (
    VALUES ('A', date '1997-01-04', date '1998-01-04'),
        ('A', date '1998-01-04', date '1998-05-27'),
        ('A', date '1998-05-27', date '1999-01-04'),
        ('B', date '1997-01-04', date '1998-01-04'),
        ('B', date '1998-01-04', date '1998-07-26'),
        ('B', date '2012-01-04', date '2013-01-04')
)

-- query
select ref,
    min(from_date) from_date,
    max(to_date) to_date,
    max(grp) over(partition by ref) + 1 count_ranges
from(
        select ref,
            from_date,
            to_date,
            sum(if(grp > 0, 1, 0)) over(partition by ref order by from_date, to_date) as grp
        from (
                select *,
                    coalesce(
                        date_diff('day', lag(to_date) over(partition by ref order by from_date, to_date), from_date),
                        0
                    ) as grp
                from dataset
            )
    )
group by ref, grp

输出:

ref from_date to_date count_ranges
A 1997-01-04 1999-01-04 1
B 1997-01-04 1998-07-26 2
B 2012-01-04 2013-01-04 2

感谢@Guru Stron,您指导我找到了正确的解决方案!

我通过在初始数据库中添加一列来升级您的代码:

select v.*,
       max(delete_timestamp) over (partition by license_plate 
       order by create_timestamp, delete_timestamp ROWS UNBOUNDED PRECEDING) 
       as moving_max

from vehicles v

结束然后我将下一个 create_timestamp 与上一个 moving_max 进行比较而不是上一个 delete_timestamp

尚未检查您的代码部分。但如果它以前工作(不是我想要的,而是你想要的;))并且我更新的数据库在新列中看起来不错(每个牌照的 moving_max 计算正确)所以它不会出错.