5

我有一张桌子bank_accounts

    Column     |         Type          |                                Modifiers                                | Storage  | Stats target | Description 
---------------+-----------------------+-------------------------------------------------------------------------+----------+--------------+-------------
 id            | integer               | not null default nextval('bank_accounts_id_seq'::regclass)              | plain    |              | 
 name          | character varying(50) |                                                                         | extended |              | 
 bank_accounts | jsonb                 | not null                                                                | extended |              | 

它在jsonb列中有一些 JSON:

 id | name  |                              bank_accounts                               
----+-------+--------------------------------------------------------------------------
  1 | test1 | [{"name": "acct1", "balance": -500}, {"name": "acct2", "balance": -300}]

我正在使用 jsonb_array_elements 获取一个用户的帐户列表:

select jsonb_array_elements(bank_accounts)->>'name' as name, jsonb_array_elements(bank_accounts)->>'balance' as balance from bank_accounts;
 name  | balance 
-------+---------
 acct1 | -500
 acct2 | -300

这一切都很棒。但是如何让每一行都有一个唯一的 id?我想将每一行映射到一个休眠对象,但是我在这样做时遇到了麻烦,因为我找不到让每一行都具有唯一 ID 的方法。

4

1 回答 1

7

尝试一种不同的、干净的方法JOIN LATERAL

select b.id, t.rn
     , t.account->>'name' AS name
     , t.account->>'balance' AS balance
FROM   bank_accounts b
LEFT   JOIN LATERAL jsonb_array_elements(b.bank_accounts)
                    WITH ORDINALITY AS t (account, rn) ON true;

如果您不关心 中具有空值或空值的行bank_accounts,请使用更简单的CROSS JOIN

select b.id, t.rn
     , t.account->>'name' AS name
     , t.account->>'balance' AS balance
FROM   bank_accounts b
     , jsonb_array_elements(b.bank_accounts) WITH ORDINALITY AS t (account, rn);

您的问题的关键要素是WITH ORDINALITY为集合返回函数动态生成行号。它是在 Postgres 9.4 中引入的——为你工作,jsonb也是在 9.4 中引入的。

这些对于每个基础行都是唯一的。要在整个表中唯一,请添加id基础表的 。

详细信息WITH ORDINALITY

有关的:

于 2015-04-13T12:10:27.767 回答