PostgreSQL select 查询(GPS)
PostgreSQL select query (GPS)
问题!
我有一个 PostgreSQL 数据库,用于保存汽车的 GPS 数据。现在我正在准备历史报告,我必须根据每辆车的速度向它们显示两个不同的状态,如果车速在 5 分钟内保持为 0,则首先 stoped,如果超过 5 分钟则我必须出示停车位。我每 10 秒从 GPS 获取数据。有什么办法吗?感谢您的帮助。
这里是 table 结构:
CREATE TABLE gps_data_abl_soft
(
id bigint NOT NULL DEFAULT nextval('gps_data_id_seq'::regclass),
device_id bigint NOT NULL DEFAULT (-1),
keyword character varying(30),
coordinate geometry,
date_time timestamp without time zone NOT NULL DEFAULT now(),
message character varying(200) NOT NULL DEFAULT ''::character varying,
speed real NOT NULL DEFAULT 0.0,
angle real NOT NULL DEFAULT 0.0,
CONSTRAINT gps_data_pkey PRIMARY KEY (id)
)
Here is the sample data from my table:
我已经通过创建 PostgreSQL 函数自己解决了这个问题!
-- Function: stop_func(bigint)
-- DROP FUNCTION stop_func(bigint);
CREATE OR REPLACE FUNCTION stop_func(IN device_id_param bigint)
RETURNS TABLE(coordinate geometry, difference interval) AS
$BODY$
DECLARE
r record;
stop_records stop_record[];
speed_zero boolean;
prev_date_time timestamp;
coordinate geometry;
BEGIN
speed_zero:=false;
for r in SELECT g.coordinate, g.date_time, g.speed FROM gps_data_abl_soft g WHERE g.device_id=device_id_param ORDER BY g.date_time
LOOP
IF r.speed=0 THEN
IF NOT speed_zero THEN prev_date_time:=r.date_time; coordinate=r.coordinate; END IF;
speed_zero:=true;
ELSE
IF speed_zero THEN
stop_records=array_append(stop_records,(coordinate, r.date_time-prev_date_time)::stop_record);
END IF;
speed_zero:=false;
END IF;
END LOOP;
RETURN QUERY SELECT * FROM unnest(stop_records);
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION stop_func(bigint)
OWNER TO dr;
这个函数的用法
SELECT ST_AsGeoJSON(ST_Transform(ST_Multi(ST_Union(coordinate)), 4326)) AS coordinate,
difference from stop_func(device_id, start_time, end_time) group by difference;
示例结果在这里:
问题!
我有一个 PostgreSQL 数据库,用于保存汽车的 GPS 数据。现在我正在准备历史报告,我必须根据每辆车的速度向它们显示两个不同的状态,如果车速在 5 分钟内保持为 0,则首先 stoped,如果超过 5 分钟则我必须出示停车位。我每 10 秒从 GPS 获取数据。有什么办法吗?感谢您的帮助。
这里是 table 结构:
CREATE TABLE gps_data_abl_soft
(
id bigint NOT NULL DEFAULT nextval('gps_data_id_seq'::regclass),
device_id bigint NOT NULL DEFAULT (-1),
keyword character varying(30),
coordinate geometry,
date_time timestamp without time zone NOT NULL DEFAULT now(),
message character varying(200) NOT NULL DEFAULT ''::character varying,
speed real NOT NULL DEFAULT 0.0,
angle real NOT NULL DEFAULT 0.0,
CONSTRAINT gps_data_pkey PRIMARY KEY (id)
)
Here is the sample data from my table:
我已经通过创建 PostgreSQL 函数自己解决了这个问题!
-- Function: stop_func(bigint)
-- DROP FUNCTION stop_func(bigint);
CREATE OR REPLACE FUNCTION stop_func(IN device_id_param bigint)
RETURNS TABLE(coordinate geometry, difference interval) AS
$BODY$
DECLARE
r record;
stop_records stop_record[];
speed_zero boolean;
prev_date_time timestamp;
coordinate geometry;
BEGIN
speed_zero:=false;
for r in SELECT g.coordinate, g.date_time, g.speed FROM gps_data_abl_soft g WHERE g.device_id=device_id_param ORDER BY g.date_time
LOOP
IF r.speed=0 THEN
IF NOT speed_zero THEN prev_date_time:=r.date_time; coordinate=r.coordinate; END IF;
speed_zero:=true;
ELSE
IF speed_zero THEN
stop_records=array_append(stop_records,(coordinate, r.date_time-prev_date_time)::stop_record);
END IF;
speed_zero:=false;
END IF;
END LOOP;
RETURN QUERY SELECT * FROM unnest(stop_records);
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION stop_func(bigint)
OWNER TO dr;
这个函数的用法
SELECT ST_AsGeoJSON(ST_Transform(ST_Multi(ST_Union(coordinate)), 4326)) AS coordinate,
difference from stop_func(device_id, start_time, end_time) group by difference;
示例结果在这里: