postgresql - 将 hstore 分解为行内的新列

标签 postgresql dynamic-sql hstore

我在 PostgreSQL 中有下表。 hstore扩展已激活。

<表类=“s-表”> <标题> osm_id hstore_column <正文> 172544 "路边"=>"降低"、"高速公路"=>"人行横道"、"人行横道"=>"有标记"、"crossing_ref"=>"斑马线"、"tactile_paaving"=>"是"、"crossing_island "=>"是", "crossing_markings"=>"斑马" 172548 “巴士”=>"is",“名称”=>“伦敦大街”,“ref_BVG”=>“103010”,“网站”=>“https_//qr.bvg.de/h103010”,“public_transport"=>"stop_position" 458330 "ref"=>"7"、"name"=>"Kaiserdamm"、"highway"=>"motorway_junction"、"destination"=>"Kaiserdamm"

我想爆炸hstore_column每个键的列。

表格标题应该变成

<表类=“s-表”> <标题> osm_id 路边 高速公路 十字路口 crossing_ref 触觉 crossing_island crossing_markings 巴士 姓名 ref_BVG 网站 公共(public)交通 引用 目的地 <正文> 172544 降低 十字路口 已标记 斑马 是 是 斑马

这个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;

fiddle

隐含的CROSS JOIN LATERAL是安全的,因为 populate_record()总是返回一行。 (返回“无行”的集合返回函数将消除结果行,您可能需要使用 LEFT JOIN ... ON true 。)

与替代可行解决方案相关的答案,其中一个详细说明了 SELECT 中的所有键列表,其中一个使用 crosstab()来自附加模块tablefunc :

关于postgresql - 将 hstore 分解为行内的新列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77508648/

相关文章:

python - 在 PL/Python 函数之间重用纯 Python 函数

postgresql - 我如何发现 PostgreSQL 数据库的结构?

node.js - PostgreSQL "column "foo“不存在”,其中 foo 是值

xml - 在 xml 中插入属性时获取 'The argument 1 of the xml data type method "修改“必须是字符串文字”

Postgresql 函数 - 使用文本类型的 VARIADIC 参数

ruby-on-rails - 了解 "attribute_will_change!"方法

ruby - Rails update_all 与 hstore

sql - 多对一关系,只选择祖先满足所有条件的行

mysql - 如何在存储过程中使用准备好的语句分配变量?

sql - 按 Postgres hstore 属性排序未按预期工作