How to get a count even if there are no results corresponding mysql?

后端 未结 4 734
暗喜
暗喜 2020-12-11 02:47

I am formalating a query to give the number of reports submitted over the last year ordered by date. I get the current year and month with php:

$year = date         


        
相关标签:
4条回答
  • 2020-12-11 03:26

    count(col_name) AS count will give you count 0

    For reference you can visit http://www.mysqlperformanceblog.com/2007/04/10/count-vs-countcol/

    0 讨论(0)
  • 2020-12-11 03:37

    You should LEFT JOIN this table with 1..12 table. Something like this:

    SELECT  Months.id AS `month` ,
    COUNT(`reports`.date_lm) AS `count`
    FROM 
    (
      SELECT 1 as ID UNION SELECT 2 as ID UNION  SELECT 3 as ID UNION SELECT 4 as ID 
      UNION  
      SELECT 5 as ID UNION SELECT 6 as ID UNION SELECT 7 as ID UNION SELECT 8 as ID 
      UNION  
      SELECT 9 as ID UNION SELECT 10 as ID UNION SELECT 11 as ID UNION SELECT 12 as ID
    ) as Months
    LEFT JOIN `reports` on Months.id=month(`reports`.date_lm)
                           AND 
                           (status = 'submitted') 
                           AND (date_lm > 2012-08)
    GROUP BY Months.id 
    ORDER BY Months.id ASC
    

    SQL Fiddle demo

    0 讨论(0)
  • 2020-12-11 03:42

    Hope this can help..

    SELECT
        t1.month_year AS month,
        COALESCE(SUM(t1.total+t2.total), 0) AS count
    FROM
    (
      SELECT 
      DATE_FORMAT(a.Date, "%Y-%m") AS md,
        DATE_FORMAT(a.Date, "%b-%y") AS month_year,
      '0' AS  total
      FROM (
        SELECT curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) 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
      ) a
      WHERE a.Date <= NOW() AND a.Date >= Date_add(Now(),INTERVAL - 11 MONTH)
      GROUP BY md
    )t1
    LEFT JOIN
    (
      SELECT DATE_FORMAT(created_at, "%b") AS month, COUNT(*) AS total ,DATE_FORMAT(created_at, "%Y-%m") AS md
      FROM reports
      WHERE created_at <= NOW() AND created_at >= Date_add(Now(),INTERVAL - 11 MONTH) AND `status` = 1
      GROUP BY md
    )t2 
    ON t2.md = t1.md
    LEFT JOIN
    (
      SELECT DATE_FORMAT(date_lm, "%b") AS month, COUNT(*) AS total ,DATE_FORMAT(date_lm, "%Y-%m") AS md
      FROM tbl_users 
      WHERE date_lm <= NOW() AND date_lm >= Date_add(Now(),INTERVAL - 11 MONTH) AND status = 'submitted'
      GROUP BY md
    )t3 
    ON t3.md = t1.md 
    GROUP BY t1.md
    ORDER BY t1.md
    

    this will give data for last 12 months even if there is no data for it with a 0..

    0 讨论(0)
  • 2020-12-11 03:51

    In order to do this, you could create a 'month' table and then use a left outer join between that table and the reports table.

    I've never used mysql so apologies if the syntax is slightly off, but this would be the query:

    SELECT months.monthNumber,
        count(reports.id) AS `count`
    FROM `months` left outer join `reports` on months.monthNumber = month(reports.date_lm) 
    WHERE (status = 'submitted') 
    AND (date_lm > 2012-08) 
    GROUP BY monthNumber
    ORDER BY monthNumber ASC
    

    Importantly, the count should be of a column in the reports table, not the months table, or else you would never get a zero.

    0 讨论(0)
提交回复
热议问题