查询以查找空闲时间,即 GPS lat long 在 15 分钟内显示相同的坐标
Query to find idle time i.e GPS lat long showing same coordinates within 15 minutes
我在 postgres 中的 GPS table 具有包含四个字段的模式,如用户 ID (int)、纬度 (float8)、经度 (float8)、记录时间 (时间戳)。
对于每个用户,我们每分钟获得 2 条记录。
需要查询以查找在相同 GPS 经纬度值上花费超过 15 分钟的用户吗?
示例记录可以是
Userid, Latitiude, Longitude, recordedtime
============================================
'ID1',12.089475408,76.089890,2019-11-24 19:10:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
'ID1',12.089475408,76.089890,2019-11-24 19:11:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
'ID1',12.089475408,76.089890,2019-11-24 19:12:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
....
..
有人可以提供所需的查询吗?
这个 CTE
可能就是您要找的。
WITH j AS (
SELECT userid,longitude,latitude,
max(recordedtime)-min(recordedtime) AS timespent
FROM t
GROUP BY userid,longitude,latitude
) SELECT * FROM j
WHERE timespent > interval '15 minute';
userid | longitude | latitude | timespent
--------+-----------+-----------+-----------
ID1 | 80.205480 | 13.082240 | 00:20:00
(1 Zeile)
你考虑过用PostGIS
来处理你的积分吗?您的用例看起来非常简单,但很快您可能会发现自己难以在 PostGIS 中已解决的数据模型中执行地理空间操作。
如果您有兴趣,请按照以下步骤创建基于 GPS 坐标的几何列:
ALTER TABLE t ADD COLUMN geom GEOMETRY;
UPDATE t SET geom = ST_SetSRID(ST_MakePoint(longitude, latitude),4326);
ST_SetSRID
函数中的值4326代表Reference System WGS84。看看哪个适合你的坐标。
这就是查询的样子:
WITH j AS (
SELECT userid,geom,
max(recordedtime)-min(recordedtime) AS timespent
FROM t
GROUP BY userid,geom
) SELECT userid,ST_AsText(geom),timespent FROM j
WHERE timespent > interval '15 minute';
userid | st_astext | timespent
--------+--------------------------+-----------
ID1 | POINT(80.20548 13.08224) | 00:20:00
(1 Zeile)
注意:如@JGH所述,此用例假设坐标相同以计算花费的时间一定的位置。您的坐标有六位小数,因此精度为 0.111 m
。长话短说,坐标偏离几米就不行了。在使用 ST_Buffer
you can easily create a buffer of a given size and with ST_Within
的 PostGIS 中,您可以检查您的某个点是否在缓冲区内。下面的查询应该给出如何执行此操作的想法:
(缓冲区50米)
WITH j AS (
SELECT userid, recordedtime, geom,
ST_Buffer(geom::GEOGRAPHY,50)::GEOMETRY AS buffer
FROM t
) SELECT t.userid, max(t.recordedTime)-min(t.recordedTime) AS timespent
FROM t,j
WHERE t.userid=j.userid AND ST_Within(t.geom,j.buffer)
GROUP BY t.userid
HAVING max(t.recordedTime)-min(t.recordedTime) > INTERVAL '15 minute';
userid | timespent
--------+-----------
ID1 | 00:22:00
(1 Zeile)
我在 postgres 中的 GPS table 具有包含四个字段的模式,如用户 ID (int)、纬度 (float8)、经度 (float8)、记录时间 (时间戳)。 对于每个用户,我们每分钟获得 2 条记录。
需要查询以查找在相同 GPS 经纬度值上花费超过 15 分钟的用户吗?
示例记录可以是
Userid, Latitiude, Longitude, recordedtime
============================================
'ID1',12.089475408,76.089890,2019-11-24 19:10:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
'ID1',12.089475408,76.089890,2019-11-24 19:11:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
'ID1',12.089475408,76.089890,2019-11-24 19:12:01
'ID1',12.089475408,76.089890,2019-11-24 19:10:31
....
..
有人可以提供所需的查询吗?
这个 CTE
可能就是您要找的。
WITH j AS (
SELECT userid,longitude,latitude,
max(recordedtime)-min(recordedtime) AS timespent
FROM t
GROUP BY userid,longitude,latitude
) SELECT * FROM j
WHERE timespent > interval '15 minute';
userid | longitude | latitude | timespent
--------+-----------+-----------+-----------
ID1 | 80.205480 | 13.082240 | 00:20:00
(1 Zeile)
你考虑过用PostGIS
来处理你的积分吗?您的用例看起来非常简单,但很快您可能会发现自己难以在 PostGIS 中已解决的数据模型中执行地理空间操作。
如果您有兴趣,请按照以下步骤创建基于 GPS 坐标的几何列:
ALTER TABLE t ADD COLUMN geom GEOMETRY;
UPDATE t SET geom = ST_SetSRID(ST_MakePoint(longitude, latitude),4326);
ST_SetSRID
函数中的值4326代表Reference System WGS84。看看哪个适合你的坐标。
这就是查询的样子:
WITH j AS (
SELECT userid,geom,
max(recordedtime)-min(recordedtime) AS timespent
FROM t
GROUP BY userid,geom
) SELECT userid,ST_AsText(geom),timespent FROM j
WHERE timespent > interval '15 minute';
userid | st_astext | timespent
--------+--------------------------+-----------
ID1 | POINT(80.20548 13.08224) | 00:20:00
(1 Zeile)
注意:如@JGH所述,此用例假设坐标相同以计算花费的时间一定的位置。您的坐标有六位小数,因此精度为 0.111 m
。长话短说,坐标偏离几米就不行了。在使用 ST_Buffer
you can easily create a buffer of a given size and with ST_Within
的 PostGIS 中,您可以检查您的某个点是否在缓冲区内。下面的查询应该给出如何执行此操作的想法:
(缓冲区50米)
WITH j AS (
SELECT userid, recordedtime, geom,
ST_Buffer(geom::GEOGRAPHY,50)::GEOMETRY AS buffer
FROM t
) SELECT t.userid, max(t.recordedTime)-min(t.recordedTime) AS timespent
FROM t,j
WHERE t.userid=j.userid AND ST_Within(t.geom,j.buffer)
GROUP BY t.userid
HAVING max(t.recordedTime)-min(t.recordedTime) > INTERVAL '15 minute';
userid | timespent
--------+-----------
ID1 | 00:22:00
(1 Zeile)