json - 将json结构转换为行

标签 json postgresql

我有一个像这样的表:

CREATE TABLE myrecord AS
id INT
other TEXT
attributes JSONB

属性的结构如下:

[
   {"name": "a", "value": "1"},
   {"name": "b", "value": "2"}
]

我想将其转换为如下结果:

id INT, other TEXT, a TEXT, b TEXT

这样对于给定的一行

1 | "foo" | {..as above..}

我得到这样的结果

1 | "foo" | "1" | "2"

现在我可以像这样解压属性结构:

CREATE TYPE myrecord_attributes AS (name TEXT, value TEXT);

SELECT
   id,
   other,
   (json_populate_recordset(NULL :: myrecord_attributes,
                            attributes :: JSON)).*
FROM myrecord

但是这样我得到的结果如下:

1 | "foo" | "a" | "1"
1 | "foo" | "b" | "2"

如何将 json_populate_recordset 的结果扁平化为适当的结构?我也愿意接受根本不使用它的替代解决方案。

如果重要的话,我正在使用 postgres 9.4

最佳答案

你可以这样做:

select m.id, 
       m.other, 
       x.value::jsonb->>'name' as name, 
       x.value::jsonb->>'value' as value
  from myrecord m, 
       json_array_elements(m.attributes) x;

如果您希望它返回带双引号的值,只需将 ->> 更改为 ->

在这里查看它的工作情况:http://sqlfiddle.com/#!15/450cc/9

这是利用隐式 LATERAL JOIN在 Postgres 9.3 或更高版本中。

编辑

我的第一个解决方案不符合 OP 的要求,因此,我创建了另一个解决方案:

select m.id, 
       m.other, 
       max(case when x.value::json->>'name' = 'a' 
                  then x.value::json->>'value' else '' end) as a,
       max(case when x.value::json->>'name' = 'b' 
                  then x.value::json->>'value' else '' end) as b
  from myrecord m, 
       json_array_elements(m.attributes) x
 group by m.id, 
          m.other;

在这里查看它的工作情况:http://sqlfiddle.com/#!15/450cc/14

关于json - 将json结构转换为行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36222954/

相关文章:

php - 从 Ajax 格式化 jQuery 数据表的 PHP/Mysql 数据

javascript - Ember : Change model's primary key with FixtureAdapter

javascript - 根据if条件选择ajax url

php - 如何检查从用户那里获取的 PostgreSQL 日期时间格式字符串的有效性?

mysql - SQL View 中需要额外的行

ruby-on-rails - 在 Rails 3 中返回空 JSON 响应的首选方法是什么?

ios - Swift:有关 JSON 解析的帮助

Spring crud 存储库按不区分大小写的字符串排序

sql - 如何使用 Join 而不是 Rails 4 中的子查询来编写此 ActiveRecord 查询

R连接到postgres在dbExistsTable中返回false,但这是错误的