0

I have a table called diary which includes columns listed below:

| id | user_id | custom_foods       |
|----|---------|--------------------|
| 1  | 1       | {"56": 2, "42": 0} |
| 2  | 1       | {"19861": 1}       |
| 3  | 2       | {}                 |
| 4  | 3       | {"331": 0}         |

I would like to count how many diaries having custom_foods value(s) larger than 0 each user have. I don't care about the keys, since the keys can be any number in string.

The desired output is:

| user_id | count   |
|---------|---------|
| 1       | 2       |
| 2       | 0       |
| 3       | 0       |

I started with:

select *
from diary as d
join json_each_text(d.custom_foods) as e
on d.custom_foods != '{}'
where e.value > 0

I don't even know whether the syntax is correct. Now I am getting the error:

ERROR: function json_each_text(text) does not exist
LINE 3: join json_each_text(d.custom_foods) as e

HINT: No function matches the given name and argument types. You might need to add explicit type casts.

My using version is: psql (10.5 (Ubuntu 10.5-1.pgdg14.04+1), server 9.4.19). According to PostgreSQL 9.4.19 Documentation, that function should exist. I am so confused that I don't know how to proceed now.

Threads that I referred to:

0

1 Answer 1

0

Your custom_foods column is defined as text, so you should cast it to json before applying json_each_text. As json_each_text by default does not consider empty jsons, you may get the count as 0 for empty jsons from a separate CTE and do a UNION ALL

WITH empty AS
  ( SELECT DISTINCT user_id,
                    0 AS COUNT
   FROM diary
   WHERE custom_foods = '{}' )
SELECT user_id,
       count(CASE
                 WHEN VALUE::int > 0 THEN 1
             END)
FROM diary d,
     json_each_text(d.custom_foods::JSON)
GROUP BY user_id
 UNION ALL
   SELECT *
FROM empty
ORDER BY user_id;

Demo

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

Comments

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.