我有一个基本的查询,该查询从google自动完成转储的数据中获取行,其中包含place_id,格式化的地址和一个包含整个json对象的json列。我相信我正在使用Postgres 10或11。
WITH
t AS (
SELECT place_id,formatted,full_json
FROM addresses_autocomplete
WHERE json_array_length(full_json) > 7
),
r AS (
SELECT short_name FROM regions WHERE regions.country_id = 1
)
SELECT DISTINCT ON(place_id)
t.full_json->5->'short_name' AS state,
t.full_json->7->'long_name' as postal_code,
full_json->3->'short_name' AS city
FROM t
INNER JOIN r ON r.short_name = t.full_json->5->>'short_name'
WHERE t.formatted=$1;
有什么办法可以写我的查询,使t.full_json->5->'short_name'
不再重复?
[类似于@Abelisto commented,您不能从同一命令的SELECT
(或WHERE
)子句引用JOIN
列表表达式,因为WHERE
子句中的表达式首先被求值。考虑事件的顺序:
您需要一个子查询或CTE,以避免重复该表达式。 但是,开始时的表达式并不完全相同。您将简单文本提取为json
,并在JOIN子句中使用与实际text
相同的文本。提取本身就很棘手。试想一下:
test=# SELECT json '"foo"' #>> '{}';
?column?
----------
foo
#>>
是...的运算符]
将指定路径的JSON对象作为文本获取
将空数组作为路径(
#>>
)传递会从简单的{}
文本中提取text
。相关阅读:
json
现在,到避免重复
state
中应用上述表达式:SELECT
相当于您的原件。在此过程中,我简化了查询,内联了CTE(除非在Postgres 12之前不需要使用CTE,否则它们通常会增加成本)并添加了
SELECT DISTINCT ON (a.place_id) a.state , a.full_json -> 7 -> 'long_name' AS postal_code , a.full_json #> '{3,short_name}' AS city -- alternative syntax, btw. FROM ( SELECT full_json -> 5 -> 'short_name' AS state -- once! , full_json FROM addresses_autocomplete WHERE json_array_length(full_json) > 7 AND formatted = $1 ) a JOIN regions r ON r.short_name = t.state #>> '{}' -- key element! WHERE r.country_id = 1 -- ORDER BY place_id, ??? -- put expression(s) here to get deterministic pick
,这将需要获得确定性结果。
关于ORDER BY
和DISTINCT ON
:
ORDER BY
但是您确定要将Select first row in each GROUP BY group?,postal_code
和city
设为state
类型吗?这是一个奇怪的要求。
此外,以上查询可能不会产生最佳的查询计划。性能的关键是用最佳索引支持最有选择性的谓词。重复表达几乎没有关系。您可能需要这样:
json