创建日期 | rake_device | rounded_geo_lat | rounded_geo_lng | 闲置或移动 | 新空闲移动 |
---|---|---|---|---|---|
2024年8月1日11:27 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日10:27 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日09:27 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日08:27 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日07:27 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日06:27 | a-b | 28.29 | 76.39 | 移动 | 空闲 |
2024年8月1日05:27 | a-b | 28.28 | 76.39 | 移动 | 空闲 |
2024年8月1日05:21 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日05:12 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日04:12 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日03:12 | a-b | 28.29 | 76.39 | 空闲 | 空闲 |
2024年8月1日02:12 | a-b | 28.24 | 76.39 | 移动 | 移动 |
2024年8月1日03:13 | a-b | 28.24 | 76.39 | 移动 | 移动 |
2024年8月1日03:09 | a-b | 28.245 | 76.33129 | 移动 | 移动 |
2024年8月1日05:12 | a-b | 28.324 | 76.3921 | 空闲 | 空闲 |
2024年8月1日05:12 | a-b | 28.324 | 76.3921 | 空闲 | 空闲 |
根据以上数据,我想导出新的列
new_idle_moving
。本专栏的逻辑是:I
我必须评估
rounded_geo_lat,rounded_geo_lng
的每一对值。如果在该分区之间的任何位置找到相同的对(rake_device、created_date desc),那么它们之间的所有值都应标记为 idle
并按原样移动。
注意:如果该移动标签的前后 lat、lng 相同,我们只需将这些移动标签替换为空闲标签即可。并且数据采用增量格式,因此每个新小时都会生成新条目,因此我们必须将其与 LAT LNG 的整个列进行比较。
我尝试了以下查询,但它将所有值转换为空闲,这是错误的输出。
WITH GroupedData AS (
SELECT
created_date,
rake_device,
rounded_geo_lat,
rounded_geo_lng,
idle_or_moving,
MAX(idle_or_moving) OVER (PARTITION BY rake_device, grp ORDER BY created_date DESC) AS max_idle_or_moving
FROM (
SELECT
created_date,
rake_device,
rounded_geo_lat,
rounded_geo_lng,
idle_or_moving,
SUM(change_flag) OVER (PARTITION BY rake_device ORDER BY created_date DESC) AS grp
FROM (
SELECT
created_date,
rake_device,
rounded_geo_lat,
rounded_geo_lng,
idle_or_moving,
CASE WHEN LAG(rounded_geo_lat) OVER (PARTITION BY rake_device ORDER BY created_date DESC) = rounded_geo_lat
AND LAG(rounded_geo_lng) OVER (PARTITION BY rake_device ORDER BY created_date DESC) = rounded_geo_lng
THEN 0 ELSE 1 END AS change_flag
FROM YourTable
) AS ChangeFlag
) AS GrpAssign
)
SELECT
gd.created_date,
gd.rake_device,
gd.rounded_geo_lat,
gd.rounded_geo_lng,
gd.idle_or_moving,
CASE WHEN gd.max_idle_or_moving = 'idle' THEN 'idle' ELSE gd.idle_or_moving END AS new_idle_moving
FROM GroupedData gd
ORDER BY gd.created_date DESC;
这里是数据库小提琴链接:https://dbfiddle.uk/w5pNGy5B
尚不清楚您希望如何调节 NEW_IDLE_MOVING 列,但您可以使用 LAG() 和 LEAD() 分析函数从上一行/下一行获取数据。答案中添加了一些其他列,可以帮助您创建将“移动”更改为“空闲”的正确条件。我的最终结果有两个新列,一列具有相同的上一个和下一个值 (_AND),另一列具有上一个或下一个相同的值 (_OR)。目前尚不清楚您需要什么,因为您提到了与上一行/下一行相同的值,并且后来影响了具有相同值的所有值。不管怎样,如果你尝试实现下面的示例,你就会明白:
WITH -- S a m p l e D a t a :
data_new (CREATED_DATE, RAKE_DEVICE, ROUNDED_GEO_LAT, ROUNDED_GEO_LNG, IDLE_OR_MOVING) AS
( Select STR_TO_DATE('2024-08-01 11:27:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 10:27:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 09:27:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 08:27:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 07:27:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 06:27:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'moving' From Dual Union All
Select STR_TO_DATE('2024-08-01 05:27:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.28, 76.39, 'moving' From Dual Union All
Select STR_TO_DATE('2024-08-01 05:21:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 05:12:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 04:12:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 03:12:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.29, 76.39, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 02:12:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.24, 76.39, 'moving' From Dual Union All
Select STR_TO_DATE('2024-08-01 03:13:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.24, 76.39, 'moving' From Dual Union All
Select STR_TO_DATE('2024-08-01 03:09:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.245, 76.33129, 'moving' From Dual Union All
Select STR_TO_DATE('2024-08-01 05:12:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.324, 76.3921, 'idle' From Dual Union All
Select STR_TO_DATE('2024-08-01 05:12:00', '%Y-%m-%d %H:%i:%s'), 'a-b', 28.324, 76.3921, 'idle' From Dual
)
-- M a i n S Q L :
SELECT a.CREATED_DATE, a.RAKE_DEVICE, a.ROUNDED_GEO_LAT, a.ROUNDED_GEO_LNG,
a.IDLE_OR_MOVING,
Case When a.LAT_LNG = a.PREV_LAT_LNG And a.LAT_LNG = a.NEXT_LAT_LNG
Then 'idle'
Else a.IDLE_OR_MOVING
End "NEW_IDLE_MOVING_WITH_AND",
Case When a.LAT_LNG = a.PREV_LAT_LNG Or a.LAT_LNG = a.NEXT_LAT_LNG
Then 'idle'
Else a.IDLE_OR_MOVING
End "NEW_IDLE_MOVING_WITH_OR",
a.DATE_START, a.DATE_END
FROM
( Select CREATED_DATE, RAKE_DEVICE, ROUNDED_GEO_LAT, ROUNDED_GEO_LNG,
IDLE_OR_MOVING,
Concat(ROUNDED_GEO_LAT, ' - ', ROUNDED_GEO_LNG) "LAT_LNG",
Concat(Coalesce(Lag(ROUNDED_GEO_LAT) Over(Order By CREATED_DATE Desc), ROUNDED_GEO_LAT),
' - ',
Coalesce(Lag(ROUNDED_GEO_LNG) Over(Order By CREATED_DATE Desc), ROUNDED_GEO_LNG)
) "PREV_LAT_LNG",
Concat(Coalesce(Lead(ROUNDED_GEO_LAT) Over(Order By CREATED_DATE Desc), ROUNDED_GEO_LAT),
' - ',
Coalesce(Lead(ROUNDED_GEO_LNG) Over(Order By CREATED_DATE Desc), ROUNDED_GEO_LNG)
) "NEXT_LAT_LNG",
Coalesce(Lag(ROUNDED_GEO_LAT) Over(Order By CREATED_DATE Desc), ROUNDED_GEO_LAT) "LAT_PREV",
Coalesce(Lead(ROUNDED_GEO_LAT) Over(Order By CREATED_DATE Desc), ROUNDED_GEO_LAT) "LAT_NEXT",
Coalesce(Lag(ROUNDED_GEO_LNG) Over(Order By CREATED_DATE Desc), ROUNDED_GEO_LNG) "LNG_PREV",
Coalesce(Lead(ROUNDED_GEO_LNG) Over(Order By CREATED_DATE Desc), ROUNDED_GEO_LNG) "LNG_NEXT",
Min(CREATED_DATE) Over(Partition By Concat(ROUNDED_GEO_LAT, ' - ', ROUNDED_GEO_LNG)) "DATE_START",
Max(CREATED_DATE) Over(Partition By Concat(ROUNDED_GEO_LAT, ' - ', ROUNDED_GEO_LNG)) "DATE_END"
From data_new
Order By CREATED_DATE Desc, ROUNDED_GEO_LAT, ROUNDED_GEO_LNG
) a
/* R e s u l t :
CREATED_DATE RAKE_DEVICE ROUNDED_GEO_LAT ROUNDED_GEO_LNG IDLE_OR_MOVING NEW_IDLE_MOVING_WITH_AND NEW_IDLE_MOVING_WITH_OR DATE_START DATE_END
------------------- ----------- --------------- --------------- --------------- --------------------------- ----------------------- ------------------- --------------------
2024-08-01 11:27:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 10:27:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 09:27:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 08:27:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 07:27:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 06:27:00 a-b 28.290 76.39000 moving moving idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 05:27:00 a-b 28.280 76.39000 moving moving moving 2024-08-01 05:27:00 2024-08-01 05:27:00
2024-08-01 05:21:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 05:12:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 05:12:00 a-b 28.324 76.39210 idle idle idle 2024-08-01 05:12:00 2024-08-01 05:12:00
2024-08-01 05:12:00 a-b 28.324 76.39210 idle idle idle 2024-08-01 05:12:00 2024-08-01 05:12:00
2024-08-01 04:12:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 03:13:00 a-b 28.240 76.39000 moving moving moving 2024-08-01 02:12:00 2024-08-01 03:13:00
2024-08-01 03:12:00 a-b 28.290 76.39000 idle idle idle 2024-08-01 03:12:00 2024-08-01 11:27:00
2024-08-01 03:09:00 a-b 28.245 76.33129 moving moving moving 2024-08-01 03:09:00 2024-08-01 03:09:00
2024-08-01 02:12:00 a-b 28.240 76.39000 moving moving idle 2024-08-01 02:12:00 2024-08-01 03:13:00 */
...您可以在 https://dbfiddle.uk/NsFrZsln
进行测试