0

Suppose I have a table in PostgreSQL that has two column, Id and Doc. In the Doc column a Json object like below:

{"eid":{"a":5, "b":6, "c":9}, "time":12345}
{"eid":{"b":6, "c":9, "x":25}, "time":13255}

I would be appreciate to help me to write a query which sums up 'a' eids according to specified time. Thanks

1
  • The nearest thing that i could do is: select json_each(events.doc->'eid') from events that produced records like ('a',5). Commented Jul 12, 2015 at 9:47

2 Answers 2

3

I'm unsure what you mean by "according to specified time", but I think you want :

SELECT * FROM j;
┌───────────────────────────────────────────────────┐
│                        doc                        │
├───────────────────────────────────────────────────┤
│ {"eid": {"a": 5, "b": 6, "c": 9}, "time": 12345}  │
│ {"eid": {"b": 6, "c": 9, "x": 25}, "time": 13255} │
└───────────────────────────────────────────────────┘
(2 rows)

SELECT SUM((doc#>>'{eid,a}')::integer) 
FROM j 
WHERE (doc->>'time')::integer = 12345;
┌─────┐
│ sum │
├─────┤
│   5 │
└─────┘
(1 row)

EDIT

To get all the keys at once (you might need to change jsonb_* to json_* depending on your schema) :

SELECT key, SUM(jsonb_extract_path_text(doc, 'eid', key)::integer)
FROM j, jsonb_object_keys(doc->'eid') sub(key)
GROUP BY key
;
┌─────┬─────┐
│ key │ sum │
├─────┼─────┤
│ x   │  25 │
│ b   │  12 │
│ a   │   5 │
│ c   │  18 │
└─────┴─────┘
(4 rows)
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks a lot @Marth, if i want to have a result that each eid is sumed in a row (like <'a',5>, <'b',12>, <'c', 18> and <'x', 25> ), what should I do?
@ehsantoghian : edited my answer. However I'm unsure of how you intend to use the time value in this query, since it seems you want to take all eids at once.
Thanks @Marth, the time is used when i want to confine the output events (eid) to a period of time. For example i want to see the event between 9 AM and 5 PM.
1

To sum all values of array eid for a given time use this query:

select time, sum(value)
from (
    select
        (json_each(doc->'eid')).value::text::int,
        doc->>'time' as time
    from events 
    ) alias
group by 1
order by 1

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.