我为地址数据库设置了一个非常常见的设置:person
与company
绑定了一个联接表,company
可以有一个{{1}等等。
所有相当规范化且易于使用。但是对于搜索性能,我创建了一个物化的,非规范化的视图。我只需要一组非常有限的信息和快速查询。通常通过连接表完成的大部分内容现在都在一个数组中。根据查询,我可以直接搜索或通过address
加入。
作为我的unnest
列(zipcodes
)的补充,我想添加一个varchar[]
列,其中已经预先计算了(德国fedaral)状态,以便我不必转换查询以包含各种范围比较。
我的映射日期在这样的表中:
states
每个州都有多个范围,范围可以重叠(一个邮政编码可以用于两种不同的状态)。某些范围有CREATE TABLE zip2state (
state TEXT NOT NULL,
range_start CHARACTER VARYING(5) NOT NULL,
range_end CHARACTER VARYING(5) NOT NULL
)
。
现在,我有点知道如何将其同时转化为物化视图。通常情况下,我很想迭代地(通过触发器或在应用程序级别)执行此操作。 或者我们只是在谈论5位数,我可以创建一个大表映射zip直接表示状态,而不是通过范围(我目前最喜欢的,但有些丑陋的东西,它促使我询问是否有&#39) ;更好的方式)
在SQL中使用上面的表(或类似的东西)的任何方法吗?我在postgres 9.3,所有功能都允许......
为了完整性'这里是邮政编码的子查询:
range_start = range_end
答案 0 :(得分:1)
我建议使用.go('^')
连接而不是相关子查询来方便地同时计算两个列。可能看起来像这样:
LATERAL
如果保证参照完整性,则根本不需要加入表SELECT p.*, z.*
FROM person p
LEFT JOIN LATERAL (
SELECT array_agg(DISTINCT d.zipcode) AS zipcodes
, array_agg(DISTINCT z.state) AS states
FROM affiliation a
-- JOIN company c ON a.ins_id = c.id -- suspect you don't need this
JOIN address d ON d.com_id = a.ins_id -- c.id
LEFT JOIN zip2state z ON d.zipcode BETWEEN z.range_start AND z.range_end
WHERE a.per_id = p.id
) z ON true;
。我走捷径。
请注意,company
或varchar
的行为与预期的数字不同。例如:text
。如果所有邮政编码都有5个数字,那么您可以。
相关: