【问题标题】:Generate report by month and year in mysql在mysql中按月和年生成报告
【发布时间】:2014-04-29 07:58:49
【问题描述】:

我需要在当前日期前 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 的原因。我该如何解决这个问题?有人可以帮我吗?

有什么方法可以比较月份和年份吗?我该怎么做?

谢谢

【问题讨论】:

  • 你也必须在年份上添加一个 ON 子句:)
  • 试试on a.month = DATE_FORMAT(d.date_entered, "%b") AND a.year = DATE_FORMAT(d.date_entered, "%Y")
  • @Kickstart 非常感谢你.. 我真是个笨蛋.. :(

标签: mysql sql report


【解决方案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 

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

【讨论】:

    【解决方案2】:

    您还需要查询分组的年份,使用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,这应该与cmets中建议的效果相同。 on a.month = DATE_FORMAT(d.date_entered, "%b") AND a.year=DATE_FORMAT(d.date_entered, "%Y")

    【讨论】:

    • 非常感谢..我真是个笨蛋.. :(
    • 我用 AND 而不是 WHERE
    【解决方案3】:

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-16
      • 1970-01-01
      • 2011-03-22
      • 2014-11-22
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      相关资源
      最近更新 更多