I want to join a column with a JSON value. The problem is the JSON value is an array and I want to join the resulting UUID value from the other column to whatever matches with the JSON Array. The table name that has the JSON column(column named staffdep) is department and the other table name is staff which has the staffId column.
staffdepID column's value would be like
{"departmentID":[],"staffID":["109ec36a-42bd-42fe-9b1f-c4f479c48fda","109ec36a-42bd-42fe-9b1f-c4f479c48fda"]}
staff id column would have a unique uuid for each row. For example like '109ec36a-42bd-42fe-9b1f-c4f479c48fda', '84dfbc00-0ff4-4689-98de-1d7496bb9da1'.
The extract of the query I used was,
from department d
join staff s on s.staffId = (d.staffdep -> 'staffID' ->> 0)::uuid
The issue with the above query is as I said above, the equivalent UUID of staffID might not always be the first value in the JSON array under d.staffdep. I would need a solution for this.
Any help is highly appreciated. Thanks
You can use a JSON path condition as the join condition:
from department d
join staff s on jsonb_path_exists(d.staffdep, '$.staffID[*] ? (# == $id)', jsonb_build_object('id', s.staffid::text));
I want to join a column with a json value. The problem is the json value is within square brackets and its a uuid. Table name that has the json column(column named json) is department and the other table name is staff. The json column value would be like below,
{"title":"Manager","alternativeTitle":null,"departmentIds":["c8098u43-7d9a-3789-gt56-r78009v4r345"]}
I would like to query the departmentIds from the json column and join it with staffdepartmentID column in the staff table.
My query for the join
from staff s
join department d on d.json ->> departmentIds::json = s.staffdepartmentID
The problem I am facing is that I dont know how to remove those square brackets. Any help is highly appreciated. Thanks
Square braquets within a json data correspond to an array.
You can access any element of the array based on its position starting with 0 for the first element : array->0
So for your query you can do :
from staff s
inner join department d
on d.json -> 'departmentIds'->>0 = s.staffdepartmentID :: text
In the database (postgres 10) i work with at the moment i have a lot of columns with json format strings (text fields)
I have a hard time to search,filter and join with values inside thoose strings.
I created an example in fiddle and i hope someone can help me solve it.
https://dbfiddle.uk/?rdbms=postgres_13&fiddle=d003c1cea832e35696260b10c6b4c047
Here is my two problems i found tricky.
In table object -> configuration field i have "date_kg_later" field. It could be [] or hold more dates. In my select i want to get the highest date if it's not empty.
In table object -> object_type_cd refers on a value inside the records string in code_table. Here i want to get the title from that string back.
My goal is an output like this:
id name object_type_name date
1000 Headphones tech 2022-04-30
1001 Pencil null null
Your first question : if the json structure of your configuration field conforms the example you provide, then a solution can be :
Before Postgres 12 :
SELECT Max((c.elt->>'date_from') :: date)
FROM object
CROSS JOIN LATERAL json_array_elements(configuration->'date_kg_later') AS c(elt)
GROUP BY your_object_table_key
From and after Postgres 12 :
SELECT Max(d :: text :: date)
FROM object
CROSS JOIN LATERAL jsonb_array_elements((configuration :: jsonb)->'date_kg_later', '$[*].date_from') AS d
GROUP BY your_object_table_key
Your second question is unclear to me, needs more explanation.
Assuming I have below table structure:
And address_collection has a value of this per table row entry:
How would I be able to query a specific json object from the array based on an address_uid assigned to user_id?
JSON_EXTRACT() and its -> alias doesn't work (returns null) because as I understand, it only works on a single JSON Object.
Example:
SELECT
u.*
FROM
user u
WHERE
u.user_id = 1
AND
u.address_collection->"$.address_uid" = "a83b662f-60de-4d3d-ab05-43b0746fb2a2";
Above example yields no result due to u.address_collection->"$.address_uid" = "a83b662f-60de-4d3d-ab05-43b0746fb2a2";
Modifying that line to u.address_collection->"$[0].address_uid" = "a83b662f-60de-4d3d-ab05-43b0746fb2a2"; doesn't work either as the result of the left part returns a collection of address_uid from the object array instead of searching it.
If I have a table with a column named json_stuff, and I have two rows with
{ "things": "stuff" } and { "more_things": "more_stuff" }
in their json_stuff column, what query can I make across the table to receive [ things, more_things ] as a result?
Use this:
select jsonb_object_keys(json_stuff) from table;
(Or just json_object_keys if you're using just json.)
The PostgreSQL json documentation is quite good. Take a look.
And as it is stated in the documentation, the function only gets the outer most keys. So if the data is a nested json structure, the function will not return any of the deeper keys.
WITH t(json_stuff) AS ( VALUES
('{"things": "stuff"}'::JSON),
('{"more_things": "more_stuff"}'::JSON)
)
SELECT array_agg(stuff.key) result
FROM t, json_each(t.json_stuff) stuff;
Here is the example if you want to get the key list of each object:
select array_agg(json_keys),id from (
select json_object_keys(json_stuff) as json_keys,id from table) a group by a.id
Here id is the identifier or unique value of each row. If the row cannot be distinguished by identifier, maybe it's better to try PL/pgSQL.
Here's a solution that implements the same semantics as MySQL's JSON_KEYS(), which...:
is NULL safe (i.e. when the array is empty, it produces [], not NULL, or an empty result set)
produces a JSON array, which is what I would have expected from how the question was phrased.
SELECT
o,
(
SELECT coalesce(json_agg(j), json_build_array())
FROM json_object_keys(o) AS j (j)
)
FROM (
VALUES ('{}'::json), ('{"a":1}'::json), ('{"a":1,"b":2}'::json)
) AS t (o)
Replace json by jsonb if needed.
Producing:
|o |coalesce |
|-------------|----------|
|{} |[] |
|{"a":1} |["a"] |
|{"a":1,"b":2}|["a", "b"]|
Insert json_column and table
select distinct(tableProps.props) from (
select jsonb_object_keys(<json_column>) as props from <table>
) as tableProps
I wanted to get the amount of keys from a JSONB structure, so I'm doing something like this:
select into cur some_jsonb from mytable where foo = 'bar';
select into keys array_length(array_agg(k), 1) from jsonb_object_keys(cur) as k;
I feel it is a little bit wrong, but it works. It's unfortunate that we can't get an array directly from the json_object_keys() function. That would save us some code.