我的PostgreSQL中有两个表。
ZIP都为CHAR(5),但每个ZIP的格式均为:“ XXXXX” 5个数字。例如:“ 55555”或“ 12345”。
我要选择所有已加入ZIP的地址。 问题是,某些地址带有zip,而该地址不在ZIP表中。在这种情况下,我想加入NEAREST(BIGGER)的zip值。
我为此创建了DB函数(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)
它可以工作,但是对于ADDRESS中的12行(ZIP中约200行),查询时间几乎是 4分钟!
计划B在DB中存储了两个ZIP,一个当前,另一个用于联接。
非常感谢!
答案 0 :(得分:2)
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是下一个更大的ZIP。
DISTINCT ON
给出有序组的第一条记录。
答案 1 :(得分:0)
您已经对所提出的问题有了答案,并且对策略整体有了一些评论。我只是想跳到后面的观点,因为在前世,我写了一个邮政编码距离计算器产品。很好,回到Internet之前,但是我现在不推荐。原因如下:
有负担得起的API,可以进行路边精度的距离和接近度计算。比粗质心计算好得多。我会时不时地进行调查,但是现在不知道最好的解决方案是什么。
如果您更新了经纬度坐标,那么球面上距离的数学就非常基础了。到处都有例子。不是超高保真度,而是快速。对于阻止查询,您希望在进行更敏感的搜索之前将其过滤到一个粗糙区域,这有点好。 Postgres有一个点类型,但也许您已经在使用它。 (我相信,PostGIS支持R树,这是用于真实多边形的非常棒的索引结构。)
如果必须使用邮政编码重心,则必须定期更新数据。没有可靠的方法来为缺少的邮政编码插入坐标,您必须去获取有人计算出的坐标(“组成”,请参阅下一点。)这是USPS提供的功能: https://www.unitedstateszipcodes.org/zip-code-database/
“中心?”正如人们已经指出的,邮政编码是路线,而不是多边形。因此多边形被伪造了。然后人为选择一个中心点。它可能在湖中,而不是高保真点数据集。
具有简单触发的质心数据在很长的距离上都可以正常工作,而在密集区域则效果不佳。因此,人口越密集,结果越差。好吧,由于世界不是一个球体,从海岸到海岸也会使事情变得混乱。
ZIP代码的数字顺序不是用于衡量接近程度。几个词:夏威夷,关岛,北马里亚纳群岛,帕劳,阿拉斯加。
听起来您已经覆盖了前导零,例如01776。太好了。某些地区的开发人员(加利福尼亚,你好,我在看着你!)忘记了马萨诸塞州等邮政编码为首位为0的地方。
您显然正在处理美国数据,这通常会引发一个问题:“加拿大情况如何?”不。根据皇室法令,加拿大每10个人就有一个邮政编码。为此,使用路边一级的地址服务确实会更好。