问题
I have a table 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 | |
And it has some JSON in the jsonb
column:
id | name | bank_accounts
----+-------+--------------------------------------------------------------------------
1 | test1 | [{"name": "acct1", "balance": -500}, {"name": "acct2", "balance": -300}]
And I am using jsonb_array_elements to get a list of the accounts for one user:
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
That's all great. But how do I get each row to have a unique id? I'd like to map each row to a hibernate object, but I'm having trouble doing that because I can't find a way to get each row to have a unique id.
回答1:
Try a different, clean approach with 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;
If you don't care for rows with empty or null values in bank_accounts
, use a simpler 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);
The key element for your problem is WITH ORDINALITY
which produces row numbers on the fly for set-returning functions. It was introduced with Postgres 9.4 - works for you, jsonb
was also introduced with 9.4.
Those are unique per underlying row. To be unique across the whole table, add the id
of the underlying table.
Details for WITH ORDINALITY
:
- PostgreSQL unnest() with element number
Related:
- Query for array elements inside JSON type
- How to turn a simple json(b) int array into an integer[] in PostgreSQL 9.4+
来源:https://stackoverflow.com/questions/29604933/how-to-get-elements-with-a-unique-number-from-a-json-array-in-postgresql