我在 PostgreSQL 中有下表。 hstore
扩展已激活。
我想爆炸hstore_column
每个键的列。
表格标题应该变成
这个related answer要求 key 已知。
问题是 key 集事先是未知的。
在此related answer给定函数在 hstore 列中显示为标签的关键字方面存在问题。
有没有办法将 hstore 键动态分解为同一个表中的单列?我知道的唯一解决方案是Python,但数据库内处理更合适。
最佳答案
The issue is that the set of keys is unknown beforehand.
所以没有单一语句(到服务器的单次往返)的解决方案。我们需要一个两步流程。喜欢:
第 1 步:确定键集,并从中动态创建临时类型。 (还有各种其他方式来引导收集的信息,这似乎是最方便的):
DO
$do$
BEGIN
DROP TYPE IF EXISTS pg_temp.osm_exploded;
EXECUTE (
SELECT format('CREATE TYPE pg_temp.osm_exploded AS (%s)'
, string_agg(quote_ident(key) || ' text', ', '))
FROM (
SELECT DISTINCT key
FROM tbl, skeys(hstore_column) key
ORDER BY key
) sub
);
END
$do$;
现在目标结构已经知道了,剩下的就很简单了。
临时类型的“技巧”与临时函数的“技巧”类似。 ( Bergi 的改进。)请参阅:
请注意,Postgres 允许 maximum of 1600 columns per table row (或者如果超过其他限制则更少)。相同的限制适用于复合类型中的列数。
第 2 步: 使用 populate_record()
进行简单查询:
SELECT t.osm_id, o.*
FROM tbl t, populate_record(null::pg_temp.osm_exploded, t.hstore_column) o;
隐含的CROSS JOIN LATERAL
是安全的,因为 populate_record()
总是返回一行。 (返回“无行”的集合返回函数将消除结果行,您可能需要使用 LEFT JOIN ... ON true
。)
与替代可行解决方案相关的答案,其中一个详细说明了 SELECT
中的所有键列表,其中一个使用 crosstab()
来自附加模块tablefunc
:
关于postgresql - 将 hstore 分解为行内的新列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77508648/