如何解决PostgreSQL选择具有相同列值的行
| location_id | lat | long | speed |
------------- ------- -------- ---------
101241 0.12 1.1 0.0
------------- ------- -------- ---------
101242 0.12 1.1 0.0
------------- ------- -------- ---------
101243 0.12 1.1 0.0
------------- ------- -------- ---------
101244 1.25 0.74 7.4
------------- ------- -------- ---------
我想选择speed = 0
和lat
&& long
相同的所有位置
因此,从上面的示例答案应该是:
| location_id |
--------------
101241
--------------
101242
--------------
101243
--------------
注意:: 速度恒定为0 ,但纬度和经度取决于前一行的值
解决方法
您可以使用inner join
:
select distinct t1.id
from table_name t1
inner join table_name t2
on t1.location_id <> t2.location_id
and t1.lat = t2.lat
and t1.long = t2.long
where t1.speed = 0
and t2.speed = 0
或存在:
select t.id
from table_name t
where exists (
select *
from table_name it
where t.location_id <> it.location_id
and t.lat = it.lat
and t.long = it.long
and it.speed = 0
)
and t.speed = 0
,
我实际上将其理解为“间隔与孤岛”问题,在该问题中,您希望相邻的行具有相同的纬度和经度,并且速度为0
。
您可以使用窗口函数来实现这一点:行号之间的差为您提供孤岛:然后您可以计算每个孤岛的长度,并对这些长度进行过滤,过滤长度大于1
且速度为{{ 1}}:
0
,
另一个解决方案:
SELECT location_id
FROM device_location
WHERE (lat,long) IN (
SELECT lat,long
FROM device_location
WHERE speed = 0.0
GROUP BY lat,long
HAVING COUNT(*) > 1
);
在SQLize.online上进行测试
,如果要相邻的行,可以只使用lead()
和lag()
。 。 。但是通过使用locationid
有一点技巧:
select t.*
from (select t.*,lag(locationid) over (order by locationid) as prev_locationid,lead(locationid) over (order by locationid) as next_locationid,lag(locationid) over (partition by lat,long order by locationid) as prev_locationid_ll,lead(locationid) over (partition by lat,long order by locationid) as next_locationid_ll
from t
) t
where speed = 0 and
(prev_locationid = prev_locationid_ll or
next_locationid = next_locationid_ll
);
仅对位置ID进行比较。根据位置ID计算一个。第二个是基于纬度和经度的上一个或下一个。如果这些相同,则相邻行上的值相同。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。