栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

带有嵌套联接的PostgreSQL 9.2 row_to_json()

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

带有嵌套联接的PostgreSQL 9.2 row_to_json()

更新:在PostgreSQL
9.4这提高了很多引进的

to_json
json_build_object
json_object
json_build_array
,虽然它冗长,由于需要明确命名所有字段:

select        json_build_object(     'id', u.id,     'name', u.name,     'email', u.email,     'user_role_id', u.user_role_id,     'user_role', json_build_object(  'id', ur.id,  'name', ur.name,  'description', ur.description,  'duty_id', ur.duty_id,  'duty', json_build_object(          'id', d.id,          'name', d.name  )     )    )from users uinner join user_roles ur on ur.id = u.user_role_idinner join role_duties d on d.id = ur.duty_id;

对于旧版本,请继续阅读。


它不限于单行,只是有点痛苦。您不能使用来别名复合行类型

AS
,因此您需要使用别名子查询表达式或CTE来达到以下效果:

select row_to_json(row)from (    select u.*, urd AS user_role    from users u    inner join (        select ur.*, d        from user_roles ur        inner join role_duties d on d.id = ur.duty_id    ) urd(id,name,description,duty_id,duty) on urd.id = u.user_role_id) row;

通过http://jsonbrush:php;toolbar:false.com/产生:

{  "id": 1,  "name": "Dan",  "email": "someemail@gmail.com",  "user_role_id": 1,  "user_role": {    "id": 1,    "name": "admin",    "description": "Administrative duties in the system",    "duty_id": 1,    "duty": {      "id": 1,      "name": "script Execution"    }  }}

array_to_json(array_agg(...))
一对一的关系,您将要使用,顺便说一句。

理想情况下,上面的查询应该可以编写为:

select row_to_json(    ROW(u.*, ROW(ur.*, d AS duty) AS user_role))from users uinner join user_roles ur on ur.id = u.user_role_idinner join role_duties d on d.id = ur.duty_id;

…但是PostgreSQL的

ROW
构造函数不接受
AS
列别名。可悲的是。

值得庆幸的是,他们对它们进行了优化。比较计划:

  • 该嵌套子查询的版本 ; 与
  • 后者的嵌套
    ROW
    构造函数版本已删除别名,因此可以执行

由于CTE是优化屏障,因此将嵌套子查询版本改写为使用链接的CTE(

WITH
表达式)可能效果不佳,并且不会得出相同的计划。在这种情况下,您会一直受困于丑陋的嵌套子查询,直到我们得到一些改进
row_to_json
ROW
更直接地覆盖构造函数中的列名的方法为止。


总之,总的来说,该原则是,您想在其中创建一个带有column的json对象

a, b, c
,并且希望您可以编写非法语法:

ROW(a, b, c) AS outername(name1, name2, name3)

您可以改用标量子查询返回行类型值:

(SELECt x FROM (SELECt a AS name1, b AS name2, c AS name3) x) AS outername

要么:

(SELECT x FROM (SELECt a, b, c) AS x(name1, name2, name3)) AS outername

另外,请记住,您可以在

json
不附加引号的情况下编写值,例如,如果将a的输出放在
json_agg
row_to_json
,则内部
json_agg
结果不会被引用为字符串,它将直接合并为json。

例如在任意示例中:

SELECT row_to_json(        (SELECT x FROM (SELECt     1 AS k1,     2 AS k2,     (SELECT json_agg( (SELECT x FROM (SELECt 1 AS a, 2 AS b) x) )      FROM generate_series(1,2) ) AS k3        ) x),        true);

输出为:

{"k1":1, "k2":2, "k3":[{"a":1,"b":2},  {"a":1,"b":2}]}

请注意,

json_agg
产品
[{"a":1,"b":2}, {"a":1,"b":2}]
不会再次转义,就像
text
那样。

这意味着您可以 组成 json操作来构造行,而不必总是创建非常复杂的PostgreSQL复合类型然后调用

row_to_json
输出。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/469257.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号