4

I have a table with 3 columns in Postgres 14.2: name, name_adds, aditional.

And these rules:

  1. name and name_adds can be filled with the same value or not. Example: name (john) and name_adds (doe) or both value is (john)

  2. column additional has one of two formats:

    format 1:

    {"default":[{"value_1": 100, "value_2": 0.1},{"value_1": 200, "value_2": 0.2}], "non_default":[{"value_1": 200, "value_2": 0.1}, {"value_1": 400, "value_2": 0.1}]}

    format 2:

    [{"value_1": 10,"value_2": 11},{"value_1": 1,"value_2": 19}

  3. If (name = name_adds) sum default -> value_1

  4. If (name != name_adds) sum non_default -> value_1

How can I sum format 1 or 2 from point 2. based on the rules in point 3. and 4.?

Example table:

name name_adds additional
---------------------------------------------------------------
john john {"default":[{"value_1": 100, "value_2": 0.1}, 
 {"value_1": 200, "value_2": 0.2}],"non_default": 
 [{"value_1": 200, "value_2": 0.1}, {"value_1": 400, 
 "value_2": 0.1}]}
john doe {"default":[{"value_1": 100, "value_2": 0.1}, 
 {"value_1": 200, "value_2": 0.2}],"non_default": 
 [{"value_1": 200, "value_2": 0.1}, {"value_1": 400, 
 "value_2": 0.1}]}
downy downy [{"value_1": 10, "value_2": 11},{"value_1": 1,"value_2": 19}]
downy dan [{"value_1": 10, "value_2": 11},{"value_1": 1,"value_2": 19}]

Expected result:

name name_adds sum_result
---------------------------------------------------------------
john john 300
john doe 600
downy downy 11
downy dan 11

I tried a query in this online demo, but didn't manage to get the expected result.

Erwin Brandstetter
186k28 gold badges463 silver badges636 bronze badges
asked Jun 11, 2022 at 23:31

1 Answer 1

4
SELECT a.name, a.name_adds, sub.*
FROM test_json a
CROSS JOIN LATERAL (
 SELECT sum((obj ->> 'value_1')::int) AS sum_result -- or numeric?
 FROM json_array_elements(COALESCE(CASE WHEN name = name_adds
 THEN additional::json -> 'default'
 ELSE additional::json -> 'non_default' END
 , additional::json)) obj
 ) sub;

db<>fiddle here

This relies on additional::json -> 'default' (or 'non_default', respectively) being NULL in case of "format 2", in which case we take additional::json directly for "format 1" using COALESCE.
Then unnest with json_array_elements(), and sum extracted value_1.

The column additional should be type json (or jsonb) to begin with.

Chances are, you would be much better off with a normalized relational design replacing that highly regular JSON column completely.

answered Jun 12, 2022 at 2:53
1
  • cool it's work, you are right about additional type, I will change it. Thanks a lot Commented Jun 13, 2022 at 2:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.