PostgreSQL中如何访问动态对象或JSON的最后一个键或元素
PostgreSQL 取JSON对象最后一个元素的实现方案
根据你存储JSON用的字段类型不同,实现方式有区别:
- 如果使用
json类型存储(保留原始输入顺序、允许重复键)json类型会完整保留写入时的键排列顺序,不会自动重排、去重,配合json_each表函数加顺序标记就能直接取最后一个元素,是最适配这类流程事务场景的方案:
-- 表查询示例:假设表名为flow_transaction,JSON字段名为step_data SELECT key, value FROM flow_transaction, json_each(step_data) WITH ORDINALITY AS t(key, value, pos) -- 替换成你需要匹配的单条记录查询条件 WHERE trans_id = '你的目标事务ID' ORDER BY pos DESC LIMIT 1;
你给出的包含重复step2键的样例数据用这个方法查询,会准确返回位置最靠后的那个step2节点,和输入顺序完全一致。如果是直接调试JSON字面量,可以用下面的写法测试:
SELECT key, value FROM json_each('{ "step1":{"info":"第一步"}, "step2":{"info":"第二步"}, "step2":{"info":"重名的最后一步"} }'::json) WITH ORDINALITY AS t(key, value, pos) ORDER BY pos DESC LIMIT 1;
- 如果使用
jsonb类型存储(自动去重、按键排序存储)jsonb为了检索效率,会自动删除重复键(仅保留最后写入的重复键值)、对所有键做二进制重排,不会保留原始写入顺序。如果你的键名是step+数字的固定规律格式,可以提取键里的数字序号排序取最大值:
SELECT key, value FROM flow_transaction, jsonb_each(step_data) AS t(key, value) WHERE trans_id = '你的目标事务ID' -- 提取键名里的数字转整数排序 ORDER BY regexp_replace(key, '[^0-9]', '', 'g')::int DESC LIMIT 1;
注意:如果
jsonb字段的键名没有固定递增规律,且没有额外存储步骤顺序的冗余字段,无法准确还原原始输入的最后一个元素——这是jsonb的存储特性决定的。这类强顺序要求的流程数据,优先选json类型存储更合适。
内容的提问来源于stack exchange,提问作者Brayan Gonzalez
相关产品推荐
相关产品推荐

