在mysql中按月和年生成报告

时间:2014-04-29 07:58:49

标签: mysql sql report

我需要在当前日期之前12个月生成报告。

今天是2014-04-29。所以我的日期范围是2013-04-29到2014-04-29。

这是我的样本数据:

--------------------------------------
-- user_id | lead_id | date_entered --
--       1 |       1 | 2013-12-05   --
--       1 |       2 | 2014-03-15   --
--       1 |       3 | 2014-04-24   --
--------------------------------------

预期输出应为:

--------------------------
-- month | year | total --
--   Apr | 2013 |     0 --
--   May | 2013 |     0 --
--   Jun | 2013 |     0 --
--   Jul | 2013 |     0 --
--   Aug | 2013 |     0 --
--   Sep | 2013 |     0 --
--   Oct | 2013 |     0 --
--   Nov | 2013 |     0 --
--   Dec | 2013 |     1 --
--   Jan | 2014 |     0 --
--   Feb | 2014 |     0 --
--   Mar | 2014 |     1 --
--   Apr | 2014 |     1 --
--------------------------

这是我的问题:

select a.month, a.year, IFNULL(d.total, 0) AS total
from (
    SELECT 'Apr' month, 2013 year, 1 monthOrder UNION 
    SELECT 'May' month, 2013 year, 2 monthOrder UNION 
    SELECT 'Jun' month, 2013 year, 3 monthOrder UNION 
    SELECT 'Jul' month, 2013 year, 4 monthOrder UNION 
    SELECT 'Aug' month, 2013 year, 5 monthOrder UNION 
    SELECT 'Sep' month, 2013 year, 6 monthOrder UNION 
    SELECT 'Oct' month, 2013 year, 7 monthOrder UNION 
    SELECT 'Nov' month, 2013 year, 8 monthOrder UNION 
    SELECT 'Dec' month, 2013 year, 9 monthOrder UNION 
    SELECT 'Jan' month, 2014 year, 10 monthOrder UNION 
    SELECT 'Feb' month, 2014 year, 11 monthOrder UNION 
    SELECT 'Mar' month, 2014 year, 12 monthOrder UNION 
    SELECT 'Apr' month, 2014 year, 13 monthOrder
) AS a left join (
    SELECT date_entered, count(id) AS total 
    FROM leads AS b 
    WHERE user_id = 1 
    AND is_deleted = 0 
    AND date_entered BETWEEN "2013-04-29" AND "2014-04-29" 
    GROUP BY YEAR(b.date_entered), MONTH(b.date_entered)
) AS d on a.month = DATE_FORMAT(d.date_entered, "%b") 
ORDER BY a.monthOrder asc

我的查询输出:

--------------------------
-- month | year | total --
--   Apr | 2013 |     1 --
--   May | 2013 |     0 --
--   Jun | 2013 |     0 --
--   Jul | 2013 |     0 --
--   Aug | 2013 |     0 --
--   Sep | 2013 |     0 --
--   Oct | 2013 |     0 --
--   Nov | 2013 |     0 --
--   Dec | 2013 |     1 --
--   Jan | 2014 |     0 --
--   Feb | 2014 |     0 --
--   Mar | 2014 |     1 --
--   Apr | 2014 |     1 --
--------------------------

因为在on a.month = DATE_FORMAT(d.date_entered, "%b")我比较了Apr 2013 has a total 1的月份。我该如何解决这个问题?有人能帮助我吗?

有没有办法可以比较月份和年份?我该怎么做?

由于

3 个答案:

答案 0 :(得分:1)

您需要在分组上查询年份,使用WHERE a.year=DATE_FORMAT(d.date_entered, "%Y")作为最高选择级别的额外条件。

select a.month, a.year, IFNULL(d.total, 0) AS total
from (
    SELECT 'Apr' month, 2013 year, 1 monthOrder UNION 
    SELECT 'May' month, 2013 year, 2 monthOrder UNION 
    SELECT 'Jun' month, 2013 year, 3 monthOrder UNION 
    SELECT 'Jul' month, 2013 year, 4 monthOrder UNION 
    SELECT 'Aug' month, 2013 year, 5 monthOrder UNION 
    SELECT 'Sep' month, 2013 year, 6 monthOrder UNION 
    SELECT 'Oct' month, 2013 year, 7 monthOrder UNION 
    SELECT 'Nov' month, 2013 year, 8 monthOrder UNION 
    SELECT 'Dec' month, 2013 year, 9 monthOrder UNION 
    SELECT 'Jan' month, 2014 year, 10 monthOrder UNION 
    SELECT 'Feb' month, 2014 year, 11 monthOrder UNION 
    SELECT 'Mar' month, 2014 year, 12 monthOrder UNION 
    SELECT 'Apr' month, 2014 year, 13 monthOrder
) AS a left join (
    SELECT date_entered, count(id) AS total 
    FROM leads AS b 
    WHERE user_id = 1 
    AND is_deleted = 0 
    AND date_entered BETWEEN "2013-04-29" AND "2014-04-29" 
    GROUP BY YEAR(b.date_entered), MONTH(b.date_entered)
) AS d on a.month = DATE_FORMAT(d.date_entered, "%b") 
WHERE a.year=DATE_FORMAT(d.date_entered, "%Y")  -- this added
ORDER BY a.monthOrder asc

或者使用AND代替WHERE,这应该与评论中提出的效果相同。 on a.month = DATE_FORMAT(d.date_entered, "%b") AND a.year=DATE_FORMAT(d.date_entered, "%Y")

答案 1 :(得分:1)

您可以按照以下方式将2个字段与加入匹配:

SELECT a.month, a.year, IFNULL(d.total, 0) AS total
FROM (
    SELECT 'Apr' MONTH, 2013 YEAR, 1 monthOrder UNION 
    SELECT 'May' MONTH, 2013 YEAR, 2 monthOrder UNION 
    SELECT 'Jun' MONTH, 2013 YEAR, 3 monthOrder UNION 
    SELECT 'Jul' MONTH, 2013 YEAR, 4 monthOrder UNION 
    SELECT 'Aug' MONTH, 2013 YEAR, 5 monthOrder UNION 
    SELECT 'Sep' MONTH, 2013 YEAR, 6 monthOrder UNION 
    SELECT 'Oct' MONTH, 2013 YEAR, 7 monthOrder UNION 
    SELECT 'Nov' MONTH, 2013 YEAR, 8 monthOrder UNION 
    SELECT 'Dec' MONTH, 2013 YEAR, 9 monthOrder UNION 
    SELECT 'Jan' MONTH, 2014 YEAR, 10 monthOrder UNION 
    SELECT 'Feb' MONTH, 2014 YEAR, 11 monthOrder UNION 
    SELECT 'Mar' MONTH, 2014 YEAR, 12 monthOrder UNION 
    SELECT 'Apr' MONTH, 2014 YEAR, 13 monthOrder
) AS a LEFT JOIN (
    SELECT date_entered, COUNT(id) AS total 
    FROM leads AS b 
    WHERE user_id = 1 
    AND is_deleted = 0 
    AND date_entered BETWEEN "2013-04-29" AND "2014-04-29" 
    GROUP BY YEAR(b.date_entered), MONTH(b.date_entered)
) AS d ON a.month = DATE_FORMAT(d.date_entered, "%b") AND a.YEAR = DATE_FORMAT(d.date_entered, "%Y") 
ORDER BY a.monthOrder ASC

答案 2 :(得分:1)

我认为你应该简化并使用这个黑客...

基本上你以年/月格式格式化日期,并将其作为字符串分组,并计算。

仅此查询应该为您提供所需的所有报告。

select 
      concat( DATE_FORMAT(date_entered ,'%Y%m')) as `yearmonth`, 
      count(*) as `total` 
from 
      leads 
where 
      user_id=1 and 
      is_deleted = 0 and 
      date_entered BETWEEN "2013-04-29" AND "2014-04-29" 
group by 1 
order by date_entered 

尝试并根据您的需要进行调整。 不要添加其他列,因为它也会被这些列分组,你会得到错误的结果。