加入两个查询表结果

时间:2013-09-09 23:51:44

标签: postgresql gps geocoding plpgsql

我试图找到一种方法来解决两个不同的表上的地理编码反向查询,其中一个是街道地址/ lat lng表,另一个是来自gps跟踪器的lat lng表。

我的查询获取地理编码反向

SELECT street_name, distance(ST_SetSRID(geom, 4326), geomfromtext('POINT(-71.536252 -16.398624)', 4326)) AS dist 
FROM vias_polyline ORDER BY dist ASC, gid DESC LIMIT 1;

我查询获取最后一次广告素材排名

CREATE OR REPLACE FUNCTION gps_get_live_location (
    _imeis varchar(8)
)
RETURNS TABLE (
    imei varchar,
    date_time_process timestamp with time zone, 
    latitude double precision, 
    longitude double precision
) AS $func$
DECLARE 
    arr varchar[];
BEGIN
    arr := regexp_split_to_array(_imeis, E'\\s+');
    FOR i IN 1..array_length(arr, 1) LOOP
        RETURN QUERY SELECT 
        imei,
        date_time_process,
        latitude,
        longitude
        FROM gpstracking_device_tracks
        WHERE imei = arr[i]::VARCHAR
        AND date_time_process >= date_trunc('hour', now()) 
        AND date_time_process <= NOW()
        ORDER BY date_time_process DESC
        LIMIT 1;
    END LOOP;
    RETURN;
END;
$func$ 
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;

我需要的是一种简单查询的方法,以便在最后位置查询时获得地理编码反转

我希望有可能,我的第一个解决方案是

CREATE OR REPLACE FUNCTION gps_get_live_location (
    _imeis varchar(8)
)
RETURNS TABLE (
    imei varchar,
    device_id integer,
    date_time_process timestamp with time zone, 
    latitude double precision, 
    longitude double precision, 
    course smallint, 
    speed smallint, 
    mileage integer,
    gps_signal smallint,
    gsm_signal smallint,
    alarm_status boolean,
    gsm_status boolean,
    vehicle_status boolean,
    alarm_over_speed boolean,
    other text
) AS $func$
DECLARE 
    arr varchar[];
BEGIN
    arr := regexp_split_to_array(_imeis, E'\\s+');
    FOR i IN 1..array_length(arr, 1) LOOP
        RETURN QUERY 
        SELECT gpstracking_device_tracks.*,
        vias_polyline.urbanizaci, 
        vias_polyline.nombre_via, 
        distance(ST_SetSRID(vias_polyline.geom, 4326), ST_SetSRID(gpstracking_device_tracks.point, 4326)) AS dist
        FROM 
        (SELECT 
        gpstracking_device_tracks.imei,
        gpstracking_device_tracks.device_id, 
        gpstracking_device_tracks.date_time_process,
        gpstracking_device_tracks.latitude,
        gpstracking_device_tracks.longitude,
        gpstracking_device_tracks.course,
        gpstracking_device_tracks.speed,
        gpstracking_device_tracks.mileage,
        gpstracking_device_tracks.gps_signal,
        gpstracking_device_tracks.gsm_signal,
        gpstracking_device_tracks.alarm_status,
        gpstracking_device_tracks.gps_status,
        gpstracking_device_tracks.vehicle_status,
        gpstracking_device_tracks.alarm_over_speed,
        gpstracking_device_tracks.other,
        gpstracking_device_tracks.point
        FROM gpstracking_device_tracks
        WHERE gpstracking_device_tracks.imei = arr[i]::VARCHAR
        AND gpstracking_device_tracks.date_time_process >= date_trunc('hour', now()) 
        AND gpstracking_device_tracks.date_time_process <= NOW()
        ORDER BY gpstracking_device_tracks.date_time_process DESC
        LIMIT 1) AS gpstracking_device_tracks, vias_polyline 
        ORDER BY dist ASC, gid DESC 
        LIMIT 1;
    END LOOP;
    RETURN;
END;
$func$ 
LANGUAGE plpgsql VOLATILE SECURITY DEFINER;

然而,我并不完全确定是一个好的答案

1 个答案:

答案 0 :(得分:0)

你的方式是合理的。我建议将隐式交叉连接更改为显式连接。这提高了可读性和清晰度。然而,事实并非如此,你可以做很多事情来解决这个问题。你可以尝试的其他事情是:

  1. 将您的内联视图移动到CTE中(这具有优化含义,因此请注意它可能是赢或输,但我认为这不重要)
  2. 将您的内联视图移动到正式视图中(但是当您在其他地方重新使用它时会忘记视图中发生的事情,从而导致不必要的性能问题)。