Skip to content
Advertisement

How sum values in days intervals MySQL 5.7?

I have a server with MySQL 5.7. I have two tables. First one t contains creating dates for each id. Second table t0 contains profit records day by day for each id. I want to get columns with sums of profit for first and second 30 days for each id as well as for the first day.

SELECT t.created_at,
   t.id,
   sum(t1.profit) profit_1_week,
   sum(t2.profit) profit_2_week,
   sum(t3.profit) profit_1_day
FROM t
LEFT JOIN t0 t1 ON t.id = t.id
AND t1.inport_date BETWEEN t.created_at AND DATE_ADD(t.created_at, INTERVAL 30 DAY)
LEFT JOIN t0 t2 ON t.id = t.id
AND t2.inport_date BETWEEN DATE_ADD(t.created_at, INTERVAL 30 DAY) AND DATE_ADD(t.created_at, INTERVAL 60 DAY)
LEFT JOIN t0 t3 ON t.id = t.id
AND t3.inport_date BETWEEN t.created_at AND DATE_ADD(t.created_at, INTERVAL 1 DAY)
GROUP BY t.created_at,
         t.id
ORDER BY t.created_at

This code runs but sums are wrong because sum of the first day much more then monthly. Where I’m wrong and how to fix it?

Advertisement

Answer

Your problem statement is not that clear, but based on your attempt, I suspect that you can do conditional aggregation:

select t.created_at, t.id, 
    sum(case when t0.inport_date >= t.created_at                   and t0.inport_date < t.created_at + interval 30 day then t0.profit else 0 end) profit_1,
    sum(case when t0.inport_date >= t.created_at + interval 30 day and t0.inport_date < t.created_at + interval 60 day then t0.profit else 0 end) profit_2,
    sum(case when t0.inport_date >= t.created_at                   and t0.inport_date < t.created_at + interval  1 day then t0.profit else 0 end) profit_3
from t
left join t0 on t0.id = t.id 
group by t.created_at, t.id
order by t.created_at

The logic is to join just once, and then to use case expressions within the sum()s to choose which values should be taken into account.

I changed the date filtering logic to use half-open intervals rather than between, because it seems more relevant to me. You can adapt that as you wish according to your actual use case.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement