Oracle 根据条件对记录的时间范围进行排名

问题描述 投票:0回答:1

假设我有一个包含一些 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
子句获得此分类吗?

sql gaps-and-islands oracle12.2
1个回答
0
投票

你有一种间隙和孤岛问题,你可以通过使用窗口函数

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

演示在这里

© www.soinside.com 2019 - 2024. All rights reserved.