8
device_id | device
-----------------------------
9809      | { "name" : "printer", "tags" : [] }    
9810      | { "name" : "phone", "tags" : [{"count": 2, "price" : 77}, {"count": 3, "price" : 37} ] }

For the following postgres SQL query on a jsonb column "device" that contains array 'tags':

SELECT t.device_id, elem->>'count', elem->>'price'
FROM   tbl t, json_array_elements(t.device->'tags') elem
where t.device_id = 9809

device_id is the primary key.

I have two issues that I don't know how to solve:

  1. tags is an array field that may be empty, in which case I got 0 rows. I want output no matter tags is empty or not. Dummy values are ok.
  2. If tags contain multiple elements, I got multiple rows for the same device id. How to aggregate those multiple elements into one row?
2
  • please show json example?.. Commented Oct 13, 2017 at 5:59
  • please provide some json sample Commented Oct 13, 2017 at 7:18

1 Answer 1

6

Your first problem can be solved by using a left outer join, that will substitute NULL values for missing matches on the right side.

The second problem can be solved with an aggregate function like json_agg, array_agg or string_agg, depending on the desired result type:

SELECT t.device_id,
       jsonb_agg(elem->>'count'),
       jsonb_agg(elem->>'price')
FROM tbl t
   LEFT JOIN LATERAL jsonb_array_elements(t.device->'tags') elem
      ON TRUE
GROUP BY t.device_id;

You will get a JSON array containing just null for those rows where the array is empty, I hope that is ok for you.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks Laurenz. I tried and looks like the join takes very long time.
Sure, this query means a sequential scan. If the table is big, it will take long. No way around that.
@LaurenzAlbe WELL DONE. This saved me about a days-worth of troubleshooting!
@LaurenzAlbe is it possible to follow this approach and get an empty json array instead of an array with null?
I assume this is related to this question that I don't understand. Is your problem that count and proce are JSON null, and you want to omit those from the result? If yes, please edit your other question and clarify that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.