Reputation: 2350
I have a query as follows:
WITH "data" ("displayName","habitas","_rowId") AS (VALUES
('Moo','[{"id":"1", "name": "A"},{"id":"2", "name": "B"}]'::json,1)
,('Boo','[{"id":"3", "name": "C"},{"id":"2", "name": "B"}]'::json,2))
SELECT
t.id, "data"."_rowId", t.name
FROM "data"
CROSS JOIN
json_to_recordset("data"."habitas") as t("id" text, "name" text)
and it returns results as:
id | _rowId | name
1 |1 | A
2 |1 | B
3 |2 | C
2 |2 | B
I actually want the results to be grouped by the id column so I've produced this SQL after some trial and error:
WITH "data" ("displayName","habitas","_rowId") AS (VALUES
('Moo','[{"id":"1", "name": "A"},{"id":"2", "name": "B"}]'::json,1)
,('Boo','[{"id":"3", "name": "C"},{"id":"2", "name": "B"}]'::json,2))
SELECT
t.id, array_agg("data"."_rowId"), t.name
FROM "data"
CROSS JOIN
json_to_recordset("data"."habitas") as t("id" text, "name" text)
GROUP BY t.id, t.name
and this then produces the correct results:
id | _rowId | name
1 |{1} | A
2 |{2} | C
3 |{1,2} | B
It's fairly ok looking and seems to work but I'm wondering if I've missed any tricks to construct this query in a better way?
Upvotes: 2
Views: 3314
Reputation: 32161
A few minor points:
"data"
and the function json_to_recordset()
you are effectively not making an unqualified join between two row sources but a join between a row from "data"
and whichever rows the function produces. The CROSS JOIN
clause implies an unqualified join and it obscures the fact that this is a lateral join (so I liked your original version better, if the LEFT
clause is removed). In a case like this I would simply use the good ol' comma ,
list: FROM "data", json_to_recordset("data"."habitas")
."
around identifiers consistently."_rowId"
values are in order in the array, then you should use array_agg("data"."_rowId" ORDER BY "data"."_rowId")
.Upvotes: 2