'how to generate a histogram with entries grouped by time in postgres

I have the following data that's generated via a postgres query:

{:n 5, :p 701, :t 1644565950000000}
{:n 1, :p 700, :t 1644565950000000}
{:n 7, :p 700, :t 1644565950000000}
{:n 7, :p 700, :t 1644565956000000}
{:n 2, :p 699, :t 1644565950000000}
{:n 3, :p 701, :t 1644565956000000}
{:n 2, :p 700, :t 1644565956000000}
{:n 5, :p 699, :t 1644565956000000}
{:n 3, :p 701, :t 1644565956000000}
{:n 3, :p 700, :t 1644565962000000}
{:n 5, :p 700, :t 1644565962000000}
{:n 1, :p 700, :t 1644565962000000}
{:n 9, :p 701, :t 1644565962000000}
{:n 3, :p 701, :t 1644565962000000}
{:n 1, :p 701, :t 1644565986000000}
{:n 7, :p 701, :t 1644565962000000}
{:n 6, :p 700, :t 1644565980000000}
{:n 6, :p 700, :t 1644565962000000}
{:n 1, :p 699, :t 1644565962000000}
CREATE OR REPLACE FUNCTION get_strike_distribution(
  i_book_id UUID,
  i_interval INTEGER,
  i_start_time BIGINT,
  i_end_time BIGINT
) RETURNS JSONB AS $$

  WITH j_ret AS (SELECT
    "position" AS p,
    "amount" AS n,
    ("time_created" / (i_interval * 1000000)) * (i_interval * 1000000) AS t
  FROM "OrderStrike") SELECT jsonb_agg(j_ret) FROM j_ret;

$$ LANGUAGE 'sql'; 

I'd like to be able to get it into a distribution like this:

{1644565950000000 {701 5, 700 8, 699 2},                                                                                                        
 1644565956000000 {700 9, 701 6, 699 5},
 1644565962000000 {700 15, 701 19, 699 1},
 1644565986000000 {701 1},
 1644565980000000 {700 6}}

is there is canonical way to do it in postgres?


This is the transform done in clojure:

(->> (group-by :t [{:n 5, :p 701, :t 1644565950000000}
                   {:n 1, :p 700, :t 1644565950000000}
                   {:n 7, :p 700, :t 1644565950000000}
                   {:n 7, :p 700, :t 1644565956000000}
                   {:n 2, :p 699, :t 1644565950000000}
                   {:n 3, :p 701, :t 1644565956000000}
                   {:n 2, :p 700, :t 1644565956000000}
                   {:n 5, :p 699, :t 1644565956000000}
                   {:n 3, :p 701, :t 1644565956000000}
                   {:n 3, :p 700, :t 1644565962000000}
                   {:n 5, :p 700, :t 1644565962000000}
                   {:n 1, :p 700, :t 1644565962000000}
                   {:n 9, :p 701, :t 1644565962000000}
                   {:n 3, :p 701, :t 1644565962000000}
                   {:n 1, :p 701, :t 1644565986000000}
                   {:n 7, :p 701, :t 1644565962000000}
                   {:n 6, :p 700, :t 1644565980000000}
                   {:n 6, :p 700, :t 1644565962000000}
                   {:n 1, :p 699, :t 1644565962000000}])
     (h/map-vals (fn [arr]
                   (reduce (fn [m {:keys [n p]}]
                             (update m p (fnil #(+ % n)
                                               0)))
                           {}
                           arr))))

=> {1644565950000000 {701 5, 700 8, 699 2},
    1644565956000000 {700 9, 701 6, 699 5},
    1644565962000000 {700 15, 701 19, 699 1},
    1644565986000000 {701 1},
    1644565980000000 {700 6}})


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source