I have a data in my DB similar to next rows:
| id | code | custom |
|---|---|---|
| 1 | GOOG | [{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW"},"customBreakdownGroup":{"id":72,"name":"poland"}}] |
| 2 | GOOG | [{"customBreakdown":{"id":15,"name":"By SOW"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":17,"name":"By SOW/PO"},"customBreakdownGroup":{"id":72,"name":"poland"}}] |
| 3 | GOOG | [{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW"},"customBreakdownGroup":{"id":73,"name":"Ungrouped"}}] |
| 4 | GOOG | [{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW/PO"},"customBreakdownGroup":{"id":73,"name":"Ungrouped"}}] |
| 5 | GOOG | [] |
| 12 | AW | [{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":17,"name":"By SOW/PO"},"customBreakdownGroup":{"id":72,"name":"poland"}}] |
| 13 | AW | [{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW"},"customBreakdownGroup":{"id":73,"name":"Ungrouped"}}] |
| 14 | AW | [{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW/PO"},"customBreakdownGroup":{"id":73,"name":"Ungrouped"}}] |
| 15 | AW | [] |
making sql query I need as result all codes + customBreakdownName + customBreakdownGroupName where
- custom[any obj]->'customBreakdown'->>'name' = 'By SOW' and custom[any obj in arr]->'customBreakdownGroup'->>'name' != 'Ungrouped'
- if previous conditions doesn't met but code present, return the
codeand emptycustomBreakdownNameandcustomBreakdownGroupName
the query to table above have to return next result:
| code | customBreakdownName | customBreakdownGroupName |
|---|---|---|
| GOOG | By SOW | poland |
| GOOG | By SOW | team |
| AW | NULL | NULL |
My query that I've implemented needs more complex condition to manage last row as result.
P.S.
Or if you prefer manage solution without fiddle you can use next data.
Postgresql table and data:
CREATE TABLE a (
id int,
code text,
custom text
);
INSERT INTO a VALUES
(1,'GOOG','[{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW"},"customBreakdownGroup":{"id":72,"name":"poland"}}]'),
(2,'GOOG','[{"customBreakdown":{"id":15,"name":"By SOW"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":17,"name":"By SOW/PO"},"customBreakdownGroup":{"id":72,"name":"poland"}}]'),
(3,'GOOG','[{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW"},"customBreakdownGroup":{"id":73,"name":"Ungrouped"}}]'),
(4,'GOOG','[{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW/PO"},"customBreakdownGroup":{"id":73,"name":"Ungrouped"}}]')
,
(5,'GOOG','[]')--
--(6,''),
--(7,null)
,(12,'AW','[{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":17,"name":"By SOW/PO"},"customBreakdownGroup":{"id":72,"name":"poland"}}]'),
(13,'AW','[{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW"},"customBreakdownGroup":{"id":73,"name":"Ungrouped"}}]'),
(14,'AW','[{"customBreakdown":{"id":15,"name":"By PO"},"customBreakdownGroup":{"id":72,"name":"team"}},{"customBreakdown":{"id":14,"name":"By SOW/PO"},"customBreakdownGroup":{"id":73,"name":"Ungrouped"}}]')
,
(15,'AW','[]')--,
;
-- SELECT * FROM a;
My query (which requires a fix):
SELECT
code
-- ,custom
,arr.item_object->'customBreakdown'->>'name' as customBreakdownName
,arr.item_object->'customBreakdownGroup'->>'name' as customBreakdownGroupName
FROM a
left join jsonb_array_elements(a.custom::JSONB) with ordinality arr(item_object) on true
where arr.item_object->'customBreakdown'->>'name' = 'By SOW'
and arr.item_object->'customBreakdownGroup'->>'name' != 'Ungrouped'
-- or arr.item_object->'customBreakdown'->>'name' != 'By SOW'
-- and
-- or a.custom::jsonb = '[]'
It requires fix because returns different result:
| code | customBreakdownName | customBreakdownGroupName |
|---|---|---|
| GOOG | By SOW | poland |
| GOOG | By SOW | team |
customshould be defined asjsonb, not astextcustomisjsonbtype, you are welcome! I'll accept any correct answer.AWshould be returned - presumably the row withID = 15but not the row withID = 5where thecustomcolumn is also an empty arrayID=5(like3or4) should be skipped because we met first condition combination, in case first condition combination doesn't have any match, we need manage second condition part.