I have next Django model.
class StocksHistory(models.Model): wh_data = models.JsonField() created_at = models.DateTimeField()
I store JSON data in wh_data
.
[ { "id":4124124, "stocks":[ { "wh":507, "qty":2 }, { "wh":2737, "qty":1 } ], }, { "id":746457457, "stocks":[ { "wh":507, "qty":3 } ] } ]
Note: it’s data for one row – 2022-06-06.
I need to calculate the sum inside stocks by grouping them by wh
and by created_at
so that the output is something like this
[ { "wh":507, "qty":5, "created_at":"2022-06-06" }, { "wh":2737, "qty":1, "created_at":"2022-06-06" }, { "wh":507, "qty":0, "created_at":"2022-06-07" }, { "wh":2737, "qty":2, "created_at":"2022-06-07" } ]
I know how to group by
date, but I don’t understand how to proceed with aggregations inside JsonField
.
StocksHistory.objects.extra(select={'day': 'date( created_at )'}) .values('day') .annotate( ??? )
A solution is suitable, both through Django ORM
and through RAW SQL
.
Advertisement
Answer
WITH cte AS ( SELECT jsonb_path_query(js, '$[*].stocks.wh')::numeric AS wh, jsonb_path_query(js, '$[*].stocks.qty')::numeric AS b, _date FROM ( VALUES ('[ { "id":4124124, "stocks":[ { "wh":507, "qty":2 }, { "wh":2737, "qty":1 } ] }, { "id":746457457, "stocks":[ { "wh":507, "qty":3 } ] } ]'::jsonb)) v (js), ( VALUES ('2022-06-06'), ('2022-06-07')) ss_ (_date) ), cte2 AS ( SELECT wh, sum(b) AS qty, _date FROM cte GROUP BY 1, 3 ORDER BY 1 ) SELECT array_agg(row_to_json(cte2.*)::jsonb) FROM cte2;