简体   繁体   中英

SQL query for last 365 days report

I have a reports table with the following structure:

在此处输入图像描述

I want a SQL Query to get the report for the last 365 days by following conditions:

  1. Group dates if the same date is repeated.
  2. The days which the report is not available for the last 365 days, I need those days added to the result rows with 0 as their success and failed recipients.

I tried to get it by group by report dates

SELECT report_date, SUM(success_recipient) as success_recipient, SUM(failed_recipient) as failed_recipient FROM reports GROUP BY report_date;

and I have got the grouped result which satisfies the first condition

在此处输入图像描述

Now I need to append the rest of the days in the last 365 days to this result in which 0 as their success and failure recipients.

Expected result:

在此处输入图像描述 and so on..

MYSQL VERSION: 5.6

One way to achieve this is using "with recursive" to generate all dates you need in you output and then outer join to the rest of your query. Note: I use the number 356 as it is in your description but it seems more appropriate to use date difference as this approach does not take into account leap years. Using the query below you will get NULL values in case you have no data. If you need the value 0 you can use coalesce(sum(...), 0).

with recursive
dates as (
  select curdate()-356 dt
  union all
  select dt+1 from dates
  where dt < curdate()
)
select 
  dt report_date,
  sum(success_recipient) success_recipient, 
  sum(failed_recipient) failed_recipient
from dates
left join reports on report_date = dt
group by report_date;

From the above comments and the answer, I could write this query which gave me the expected outcome:

 SELECT a.date, SUM(COALESCE(r.success_recipient, 0)), SUM(COALESCE(r.failed_recipient, 0)) FROM ( SELECT curdate() - INTERVAL (aa + (10 * ba) + (100 * c.a) + (1000 * da) ) DAY AS date FROM (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as c cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as d ) a LEFT JOIN reports r ON a.date = r.report_date WHERE a.date between DATE_SUB(CURDATE(), INTERVAL 1 YEAR) and now() GROUP BY a.date;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM