Найти (большее) ближайшее значение для таблицы соединений - PullRequest
0 голосов
/ 11 июля 2019

У меня есть две таблицы в моем PostgreSQL.

  • АДРЕС (улица, город, почтовый индекс)
  • ZIP (zip, gps_lat, gps_long)

ZIP - CHAR (5) в обоих, но каждый ZIP имеет формат: «XXXXX» 5 цифр.Пример: «55555» или «12345».

Я хочу выбрать все АДРЕС с присоединенным ZIP.Проблема в том, что у некоторых адресов есть zip, которых нет в таблице ZIP.Для этой ситуации я хочу присоединить значение NEAREST (BIGGER).

Я создал для него функцию БД (psc == zip):

CREATE OR REPLACE FUNCTION lekari.get_psc(pscx character)
RETURNS character
LANGUAGE plpgsql
AS $function$
begin
    if exists (select 1 from spravni_celky.zip where psc = pscx) then
        return pscx;
    end if;

    while not exists (select 1 from spravni_celky.zip where psc = pscx) loop  
        pscx =  cast(cast(pscx as integer) + 1 as char(5));
    end loop;

return pscx;
end;$function$;

А затем создайте просто выберите:

select * from lekari.address lad
join spravni_celky.zip p on p.psc = lekari.get_psc(lad.psc)

Это работает, но для 12 строк в АДРЕС (и около 200 в ZIP) время запроса составляет почти 4 мин !

План B хранится в двух ZIP вБД, один текущий и один для присоединения.

Большое спасибо!

Ответы [ 2 ]

2 голосов
/ 11 июля 2019

демо: дб <> скрипка

SELECT DISTINCT ON (a.city, a.street, a.zip)
    *
FROM
    address a
JOIN
    zip z
ON a.zip <= z.zip
ORDER BY a.city, a.street, a.zip, z.zip

Присоединяйтесь ко всем ZIP, которые равны или больше. Затем выдайте первые записи для каждого присоединенного адреса.

Если zip существует: первый подходящий ZIP равен. Итак, первые заказанные записи - это собственный почтовый индекс.

Если zip не существует: первый подходящий ZIP является следующим большим.

DISTINCT ON выдает первые записи упорядоченной группы.

0 голосов
/ 13 июля 2019

У вас уже есть ответ на заданный вопрос и несколько комментариев о стратегии в целом.Я просто хочу перейти к этому более позднему моменту, так как в прошлой жизни я написал продукт для калькулятора расстояний по почтовому индексу.Это было здорово, еще до Интернета , но я бы не рекомендовал это сейчас.И вот почему:

  • Существуют доступные API для выполнения расчетов расстояния и близости с точностью на стороне обочины.Намного лучше, чем грубые вычисления центроидов.Я рассматриваю это время от времени, но не знаю, какое решение лучше в эти дни.

  • Если вы получили обновление ваших координат широты и долготы, математика для определения расстояния на сфере будет действительно базовой.Примеры есть везде.Не супер высокая точность, но быстро.Вроде как для блокирующего запроса, где вы хотите отфильтровать грубую область, прежде чем выполнять более чувствительный поиск.У Postgres есть тип точек, но, возможно, вы уже используете это.(Я полагаю, что PostGIS поддерживает R-деревья, что является довольно удивительной структурой индексов для реальных многоугольников.)

  • Если вы должны использовать центроиды ZIP-кода,Вы должны регулярно обновлять данные.Не существует надежного метода для интерполяции координат для отсутствующих почтовых индексов, вам нужно пойти и получить координаты, которые кто-то вычисляет («составленные», см. Следующий пункт). Вот что предлагает USPS: https://www.unitedstateszipcodes.org/zip-code-database/

  • "Centroid?"Как уже отмечалось, почтовый индекс - это маршрут , а не полигон .Таким образом, многоугольник подделывается.И тогда центральная точка выбирается искусственно.Это может быть в середине озера, это не набор точных данных высокой точности.

  • Данные центроида с простым триггером хорошо работают (очень) на очень больших расстояниях, и не такотлично в плотных областях.Таким образом, чем плотнее ваше население, тем хуже будет результат.Что ж, от побережья к побережью тоже все немного запутано, потому что мир - это не сфера.

  • Цифровая последовательность почтового индекса не мера близости,Несколько слов: Гавайи, Гуам, Северные Марианские острова, Палау, Аляска.

  • Звучит так, как будто вы закрыли ведущие нули, как 01776. Хорошо для вас.Разработчики в некоторых местах ( Здравствуйте, Калифорния, я смотрю на вас! ) забывают о таких местах, как, например, штат Массачусетс, где первая цифра почтового индекса - 0.

  • Вы, очевидно, имеете дело с данными США, что часто приводит к вопросу "как насчет Канады?"Нету.В Канаде есть что-то вроде одного почтового индекса на каждые 10 человек по королевскому указу или что-то в этом роде.Для этого вам бы действительно было бы лучше использовать адресную службу на уровне ограничения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...