根据 mysql 中的另一个 activity 获取行

fetch rows based on another activity in mysql

我有一个 mysql table 个 user_locations。我有如下记录

id    user_id     latitude                 longitude
 1      1         28.62584611111111        77.10560666666667
 2      1         28.62584611111111        77.10560666666667
 3      1         28.62584611111111        77.10560666666667
 4      1         28.62584611111111        77.10560666666667
 5      1         28.627457222222223       77.11092111111111
 6      1         28.627457222222223       77.11092111111111
 7      1         28.62584611111111        77.10560666666667
 8      1         28.62584611111111        77.10560666666667

现在看到id 1,2,3,4,7,8有相同的纬度和经度,id 5,6有不同的纬度和经度

如果我分组我只会得到两个结果。但我的预期输出如下:-

 id    user_id     latitude                 longitude
 4      1         28.62584611111111        77.10560666666667
 6      1         28.627457222222223       77.11092111111111
 8      1         28.62584611111111        77.10560666666667

我尝试了下面的查询,但是这给了我两个结果

SELECT * FROM `user_locations` WHERE `user_id` = 1 Group by latitude, longitude

如果相同的纬度和经度不断出现,我想找到的是它必须 return 一个最新的行,之后如果纬度和经度发生变化,那么最新的一行将会出现,如果在两者之间再次出现相同的纬度和经度来自以前的集合,也应该 return。希望你能理解我的问题。谁能帮我解决这个问题。

这是一个缺口和孤岛问题。 Islands代表相邻的行有相同的用户,经纬度,你想要每个岛的最后一条记录。

这里最简单的方法可能是使用lag()来识别latitude/longitude中的变化:

select *
from (
    select ul.*,
        lag(latitude) over(partition by user_id order by id) lag_latitude,
        lag(longitude) over(partition by user_id order by id) lag_longitude
    from user_locations ul
) ul
where latitude <> lag_latitude or longitude <> lag_longitude

这需要 MariaDB 12.2.2 或更高版本。在早期版本中,您可以使用相关子查询模拟 window 函数。对于大量行,这可能效率低下:

select *
from user_locations ul
where latitude  <> (select ul1.latitude  from user_locations ul1 where ul1.user_id = ul.user_id and ul1.id < ul.id order by ul1.id desc limit 1)
   or longitude <> (select ul1.longitude from user_locations ul1 where ul1.user_id = ul.user_id and ul1.id < ul.id order by ul1.id desc limit 1)