Sample contents are:
id | created_dt | data |
---|---|---|
1 | 2023-01-14 11:52:41 | {"customers": 1, "payments: 2} |
2 | 2023-01-15 11:53:43 | {"customers": 1, "payments: 2} |
3 | 2023-01-18 11:51:45 | {"customers": 1, "payments: 2} |
4 | 2023-01-15 11:50:48 | {"customers": 1, "payments: 2} |
ID 4 or 2 should be distinct.
I want to get a result as follows:
year | week | customers | payments |
---|---|---|---|
2023 | 2 | 2 | 4 |
2023 | 3 | 1 | 2 |
I solved this problem in this way
SELECT
date_part('year', sq.created_dt) AS year,
date_part('week', sq.created_dt) AS week,
sum((sq.data->'customers')::int) AS customers,
sum((sq.data->'payments')::int) AS payments
FROM
(SELECT DISTINCT ON (created_dt::date) created_dt, data
FROM analytics) sq
GROUP BY
year, week
ORDER BY
year, week;
However, that subquery greatly complicates the query. Is there is a better method?
I need group the data by each week, however I also need to remove duplicate days.
3
Answers
Generate series to create the join table would solve the problem :
First of all, I think your query is quite simple and understandable.
Here is the query with a
with
-query in it, in some point it adds more readabilty:The difference is that the first query uses the
DISTINCT
clause, not theDISTINCT ON
clause.Here is the sql fiddle.
You can simplify it by adding partitioning on "created_id::date", then filter last aggregated record for each week using
FETCH FIRST n ROWS WITH TIES
.Check the demo here.