假设我有一个包含一些 GPS 点及其速度属性的表格 (我们忽略这里的位置):
ID TIME SPEED
---------------------------------
1 2024-01-01 09:00:02 0
3 2024-01-01 09:00:03 0
6 2024-01-01 09:00:04 2
8 2024-01-01 09:00:09 11
14 2024-01-01 09:00:10 15
11 2024-01-01 09:00:22 22
12 2024-01-01 09:00:28 4
10 2024-01-01 09:00:32 0
15 2024-01-01 09:00:33 2
16 2024-01-01 09:00:34 8
17 2024-01-01 09:00:35 12
18 2024-01-01 09:00:38 3
我需要唯一标识 speed 为 的记录的 ranges< 5,保持
TIME
排序。
类似这样的东西(我包括了 2 个有效的替代方案:RANGE_NO 和 ALT_RANGE_NO):
ID TIME SPEED RANGE_NO ALT_RANGE_NO
---------------------------------------------------------------
1 2024-01-01 09:00:02 0 1 1
3 2024-01-01 09:00:03 0 1 1
6 2024-01-01 09:00:04 2 1 1
8 2024-01-01 09:00:09 11 (null or 0) 2
14 2024-01-01 09:00:10 15 (null or 0) 2
11 2024-01-01 09:00:22 22 (null or 0) 2
12 2024-01-01 09:00:28 4 2 3
10 2024-01-01 09:00:32 0 2 3
15 2024-01-01 09:00:33 2 2 3
16 2024-01-01 09:00:34 8 (null or 0) 4
17 2024-01-01 09:00:35 12 (null or 0) 4
18 2024-01-01 09:00:38 3 3 5
我正在尝试使用分析函数,但我无法在这种条件下通过
TIME
保持顺序(或由 RANK() over(order by TIME)
获得的等效数字)进行排名。
当然,我可以使用 LEAD()
和 LAG()
函数来识别“边缘”点,以获取下一条或上一条记录何时超过速度阈值。partition by
条件。
我总是发现,如果存在这样的条件,它将与我正在寻找的“RANGE_NO”相同。
我可以在单个查询中或通过(一些)子查询或
with
子句获得此分类吗?
你有一种间隙和孤岛问题,你可以通过使用窗口函数
LAG()
计算速度何时超过5来创建分组,如下所示:
SELECT ID, TIME, SPEED,
1+ SUM(CASE WHEN minSpeed = prevSpeed THEN 0 ELSE 1 END)
OVER (ORDER BY TIME) ALT_RANGE_NO
FROM (
SELECT ID, TIME, SPEED, minSpeed, Lag(minSpeed, 1, minSpeed) over(ORDER BY TIME) prevSpeed
FROM (
SELECT ID, TIME, SPEED, CASE WHEN SPEED < 5 THEN 1 ELSE 0 END as minSpeed
FROM mytable
)
ORDER BY TIME
)
结果:
ID TIME SPEED ALT_RANGE_NO
1 01-JAN-24 09.00.02.000000 0 1
3 01-JAN-24 09.00.03.000000 0 1
6 01-JAN-24 09.00.04.000000 2 1
8 01-JAN-24 09.00.09.000000 11 2
14 01-JAN-24 09.00.10.000000 15 2
11 01-JAN-24 09.00.22.000000 22 2
12 01-JAN-24 09.00.28.000000 4 3
10 01-JAN-24 09.00.32.000000 0 3
15 01-JAN-24 09.00.33.000000 2 3
16 01-JAN-24 09.00.34.000000 8 4
17 01-JAN-24 09.00.35.000000 12 4
18 01-JAN-24 09.00.38.000000 3 5