I can get a list of each day of last 30 days row by row with this query and it works..
But I don't think that it is the best one since the "WHERE" part is messed up. I draw a graph and I just want to get daily_total_invoice_amount for sum of each day of last 30 days.
SELECT
sum(b.invoice_amount) daily_total_invoice_amount,
extract(day from a.order_creation_date) as day,
extract(month from a.order_creation_date) as month
FROM orders a
INNER JOIN order_items b
ON a.order_id = b.order_id
WHERE
order_creation_date BETWEEN (CURRENT_DATE - INTERVAL '1 MONTH' + INTERVAL '2 DAY')
AND CURRENT_DATE + INTERVAL '1 DAY'
GROUP BY month, day
order by month DESC, day DESC
Best Answer
Why include tomorrow (
CURRENT_DATE + INTERVAL '1 DAY'
)? A future date inorder_creation_date
would normally indicate a data error. I would not even include today in the statistic, since that is typically incomplete and misleading until the day is over. Consequently I use the last 30 days up until yesterday in my query.Assuming
order_creation_date
is an actualdate
, justGROUP BY
andORDER BY
that date, that's simpler an cheaper than using extracted month and day numbers for the same. If it's not adate
, but atimestamp
ortimestamptz
, just cast todate
to group by the day:o.order_creation_date::date
. Be aware that the result depends on thetimezone
setting of the session when dealing withtimestamptz
(Day boundaries are defined by the time zone.)Also assuming you want a result row for every single one of the 30 days. To make sure, days without orders don't go missing, generate the series of days with
generate_series()
andLEFT JOIN
to that. You can generate timestamps, but I use the simpler integer variant while we are operating with dates. We can just subtract aninteger
from adate
to subtract days.