I save visits to my database. In my database I have a table with aggregations of visits called visits_agg
. This table has one row per hour
per hostname
. Both are fields in the table which will be used to query the rows needed for viewing statistics.
For example I will query for the visits in the last 24 hours:
SELECT * FROM visits_agg WHERE hostname = 'example.com' AND hour > NOW() - INTERVAL '24 hours'
To create the structure I used this query:
CREATE TABLE IF NOT EXISTS visits_agg (
id serial primary key,
hour timestamp without time zone default (now() at time zone 'utc'),
hostname text not null,
visits integer default 0,
referrers jsonb not null default '{}'::jsonb,
paths jsonb not null default '{}'::jsonb,
widths jsonb not null default '{}'::jsonb
);
With some dummy data:
INSERT INTO "visits_agg" ("hour", "hostname", "visits", "referrers", "paths", "widths") VALUES
('2019-01-16 09:00:00', 'example.com', '6', '{"example2.com": 4}', '{"/": 5, "/about": 1}', '{"1280": 5, "1283": 1}'),
('2019-01-16 14:00:00', 'example.com', '7', '{"google": 6}', '{"/": 1, "/about": 3, "/article/title1": 1, "/article/title2": 2}', '{"360": 3, "1398": 1, "1680": 1, "2560": 1}'),
('2019-01-16 15:00:00', 'example.com', '6', '{"google": 6}', '{"/about": 1, "/article/title1": 1, "/article/title2": 3, "/": 1}', '{"360": 3, "1280": 2, "1920": 1}'),
('2019-01-16 16:00:00', 'example.com', '6', '{"facebook": 1, "example2.com": 1}', '{"/": 4, "/about": 1, "/article/title1": 1}', '{"360": 1, "1440": 2, "1680": 2, "1920": 1}');
I would like to get the rows from a certain period and sum all referrers, paths, and widths.
So the result of the above records should be something like this
'example.com',
'25',
'{"example2.com": 4, "google": 12, "facebook": 1}',
'{"/": 11, "/about": 6, "/article/title1": 3, "/article/title2": 5}',
'{"360": 7, "1398": 1, "1440": 2, "1680": 3, "2560": 1, "1280": 7, "1283": 1, "1920": 2}'),
The keys in the jsonb
objects can be any string and the values are always numbers. I tried to merge the objects, but can't figure out how to sum the values inside the jsonb
objects.
Best Answer
As I pointed out in comments I think this job would be easy to accomplish working with a disaggregated data, because now IMHO you must disaggregate it again:
For example to get aggregated values for
referrers
:Now you can get acumulated values grouped by ref_name, and then you must build the jsonb array again.
This is my approach, perhaps some Postgres guru can give you a better answer.
And this is the result:
db<>fiddle here