检查日期分割周期是否连续(并找出差距)
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 排序并逐行比较不起作用)。
这个想法是将车辆(车牌)分组为:
- 'Active'(从第一个 create_timestamp 到 now/end_date 没有差距); license_plate 在我的示例中为 AA-AAA
- 'Reactivated'(至少有间隙,但汽车现在处于活动状态)- license_plate BB-BBB
- 'Deleted'(从第一个 create_timestamp 到最后一个 delete_timestamp 没有间隔,但现在不活跃)- license_plate CC-CCC
我知道可能会有更多的场景(即 '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 计算正确)所以它不会出错.
我正在努力解决与此线程中类似的问题: 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 排序并逐行比较不起作用)。 这个想法是将车辆(车牌)分组为:
- 'Active'(从第一个 create_timestamp 到 now/end_date 没有差距); license_plate 在我的示例中为 AA-AAA
- 'Reactivated'(至少有间隙,但汽车现在处于活动状态)- license_plate BB-BBB
- 'Deleted'(从第一个 create_timestamp 到最后一个 delete_timestamp 没有间隔,但现在不活跃)- license_plate CC-CCC
我知道可能会有更多的场景(即 '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 计算正确)所以它不会出错.