使用 union 优化 group by 查询

Cod*_*aru 2 mysql sql select group-by gaps-and-islands

我有一个像这样的 MySQL 表:

在此处输入图片说明

我想找到一个像这样对我的表进行分组的查询:

在此处输入图片说明

细节:

a_id = 地图上划定的区域

is_flag = 1-如果传感器在区域内/ 0-如果传感器不在区域内

基本上第一个表描述了我的传感器在每个时间戳的哪个区域。

第二个表告诉我我的传感器停留在每个区域的时间。

我对每个带有 union all 的 area_id 使用以下查询,以便在单个表中输出我的传感器如何在区域之间移动的时间段以及它在每个区域中停留的时间。

select t.a_id, min(t.timestamp) starttime,max(t.timestamp) endtime, 
t.is_flag from(SELECT *,
ROW_NUMBER() OVER(ORDER BY a.timestamp) - ROW_NUMBER() OVER(PARTITION BY 
a.is_flag ORDER BY a.timestamp) as GRP
FROM tablename a where areas_id=25 ) t
group by is_flag , GRP, a_id
Run Code Online (Sandbox Code Playgroud)

这是我的 dbfiddle:https ://www.db-fiddle.com/f/5pHiYKyx4yHoirRbGX4kP4/0

我的查询满足了我的需求,但需要花费一整天的时间。

Aki*_*ina 6

WITH 
cte1 AS (SELECT CAST(JSON_UNQUOTE(`timestamp`) AS DATETIME) ts,
                areas_id,
                is_in_or_out
         FROM inouts),
cte2 AS (SELECT ts,
                areas_id,
                is_in_or_out,
                CAST(ROW_NUMBER() OVER (PARTITION BY areas_id ORDER BY ts ASC) AS SIGNED)
               -CAST(ROW_NUMBER() OVER (PARTITION BY areas_id ORDER BY is_in_or_out, ts ASC) AS SIGNED) AS grp
         FROM cte1)
SELECT areas_id, 
       ANY_VALUE(is_in_or_out) is_in_or_out,
       MIN(ts) min_ts,
       MAX(ts) max_ts
FROM cte2 
GROUP BY areas_id, 
         grp
ORDER BY areas_id, min_ts;
Run Code Online (Sandbox Code Playgroud)

小提琴

PS1。源数据略有改动。

PS2。CAST在 MySQL 中需要,因为ROW_NUMBER()产生 bigint unsigned。可以替换为0.0 + ....