0

Our database contains a table "log" like this:

id | purchases (json)
1    {"apple":{"price":5,"seller":"frank"}, "bred":{"price":3,"seller":"kathy"}}
2    {"milk":{"price":3,"seller":"anne"}, "banana":{"price":2,"seller":"frank"}}
3    {"bred":{"price":4,"seller":"kathy"}}

We would like to retrieve all records containing "seller":"kathy". We tried simple queries like this:

SELECT id FROM log WHERE purchases ->> 'seller' LIKE 'kathy'
SELECT id FROM log WHERE purchases = '{"seller":"kathy"}'

We researched here and elsewhere for some hours ... it seems a bit more complex because the values are nested? We found e.g. some java or pgplsql implementations, but we are still hoping there is a "pure SQL" way. What would be a proper solution? Or should we re-organize our content like this:

id | purchases (json)
1    [{"product":"apple","price":5,"seller":"frank"},{"product":"bred","price":3,"seller":"kathy"}]
2    [{"product":"milk","price":3,"seller":"anne"},{"product":"banana","price":2,"seller":"frank"}]
3    [{"product":"bred","price":4,"seller":"kathy"}]

But what we found, this would be even more complex, because we have to explode the arrays within the query. Any short hint? Thanks!

1 Answer 1

1

Check json_each() and #>> Postgres JSON functions:

WITH log(id,purchases) AS ( VALUES
  (1,'{"apple":{"price":5,"seller":"frank"}, "bred":{"price":3,"seller":"kathy"}}'::JSON),
  (2,'{"milk":{"price":3,"seller":"anne"}, "banana":{"price":2,"seller":"frank"}}'::JSON),
  (3,'{"bred":{"price":4,"seller":"kathy"}}'::JSON)
)
SELECT log.* FROM log,
  json_each(log.purchases) as purchase
WHERE
  purchase.value#>>'{seller}' = 'kathy';

Result:

 id |                                  purchases                                  
----+-----------------------------------------------------------------------------
  1 | {"apple":{"price":5,"seller":"frank"}, "bred":{"price":3,"seller":"kathy"}}
  3 | {"bred":{"price":4,"seller":"kathy"}}
(2 rows)
Sign up to request clarification or add additional context in comments.

1 Comment

perfect, helps a lot, thanks @dmitry, I understand much more now.

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.