postgresql knex postgres作为嵌套JSON连接

7d7tgy0s  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(3)|浏览(167)

我在postgresql db中使用knex,我在表A中有一行,它与表B中的行有一对一关系,与表C中的行有一对多关系。
我想从A加入一行B和C,得到一个json,如

{
  aCol1: ...,
  b: {
    bCol1: ...,
    bCol2: ...,
  },
  c: [
    {
      cCol1: ...
    },
    {
      cCol1: ...
    }
  ]
}

其中,aCol表示表A中的列,bCol表示表B中的列,这是联合的。
如何通过一个查询和连接实现这一点?

l7wslrjt

l7wslrjt1#

对此使用JsonAgg
SQL语句:
选择tA.id,tA.name,json_agg(tB)作为“tA”上“tB”的左连接“tA“中的tB。“tB_id”=“tB”。“id”分组依据“tA”。“id”,“tA”。“name”
膝关节:

db('tA')
.leftJoin('tA', 'tA.tB_id', 'tB.id')
.groupBy(['tA.id', 'tA.name'])
.select(db.raw(`tA.id,tA.name,json_agg(tB) as tB`))
1bqhqjot

1bqhqjot2#

你可以使用JSON_AGG()得到你想要的。你也可以使用Postgres的JSON操作符只得到一条记录而不是很多条。如果你想避免一个大的GROUP BY子句,在你选择的主表上使用JSON_AGG()而不是选择每一列。使用你的例子,看起来像这样:

select
  a.id,
  json_agg(a.*)->0 as a_obj,
  json_agg(b.*)->0 as b_obj,
  json_agg(c.*) as c_objs
from a
left join b on b.a_id = a.id
left join c on c.a_id = a.id
group by a.id

这将给予你一个很好的干净的结果,如:

id       | 123
a_obj    | {"id":123,...}
b_obj    | {"bCol1":...,"bCol2":...}
c_objs   | [{"cCol1":...},{"cCol1":...}]
agyaoht7

agyaoht73#

您可以通过一个查询和连接来实现它,但它会变得过于复杂。您应该改用ORM。
Objection.js基于knex,允许您以一种简单且高性能的方式执行此类查询(您可以选择使用连接或多个查询,通常多个查询的性能更高)。
使用Objection.js语法时,它看起来如下所示:

const res = await ATableModel.query().where('id',  a.id).eager('[b,c]');

相关问题