繁体   English   中英

使用Count(*)进行SQL查询并选择缺少的月份

[英]SQL query with Count(*) and select missing month also

我正在使用MySQL数据库。

我想从表中计算一个月内的所有行。 该脚本为我产生了正确的输出:

SELECT Count(*) as size, DATE_FORMAT(mydate, "%Y-%m") as mydate
FROM Table
GROUP BY DATE_FORMAT(mydate, "%Y-%m") ASC

输出是带有数字和日期属性的表。 例如:

10 | 2011-01
40 | 2011-03
20 | 2011-05

我的问题是数据库中没有任何行的月份不会出现在输出中。 现在这很正常。

我想编写一个sql查询,产生如下输出:

10 | 2011-01
0  | 2011-02
40 | 2011-03
0  | 2011-04
20 | 2011-05

如果可能的话,我只想使用纯SQL语言。

谁能帮我这个SQL脚本?

我建议创建一个永久的日期表,并使其加入其中(非常方便),或者您可以制作一个临时的日期表:

CREATE TEMPORARY TABLE daterange (dte DATE); 

SET @counter := -1;
WHILE (@counter < DATEDIFF(DATE(_todate), DATE(_fromdate))) DO 
    INSERT daterange VALUES (DATE_ADD(_fromdate, INTERVAL @counter:=@counter + 1 DAY));
END WHILE;

然后将您的查询用作子查询,请进行左联接以获取缺少的日期

SELECT ifnull(data.thecount,0) as theCount, daterange.dte FROM 
daterange LEFT JOIN
(
   SELECT COUNT(*) AS theCount, DATE_FORMAT(dates.dte, "%Y-%m") as mydate
   FROM table
   GROUP BY DATE_FORMAT(dates.dte, "%Y-%m") ASC
) DATA 
    ON daterange.dte = DATA.mydate
   ORDER BY daterange.dte asc

完成后删除您的临时表:

DROP TEMPORARY TABLE daterange

编辑:左联接是非常非常错误,在此修复。 您可能需要尝试格式化

看看我的小提琴

解决方案基于日历表文章

完整列表如下:

/*Build a calendar*/
CREATE TABLE `Int` ( i tinyint );
CREATE TABLE Calendar (dt DATE NOT NULL PRIMARY KEY);
CREATE TABLE Report(
  size INT NOT NULL,
  dt CHAR(7) NOT NULL
);

INSERT INTO `Int` VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

INSERT INTO Calendar (dt)
  SELECT DATE('2010-01-01') + INTERVAL a.i*10000 + b.i*1000 + c.i*100 + d.i*10 + e.i DAY
  FROM `Int` a 
   JOIN `Int` b 
   JOIN `Int` c 
   JOIN `Int` d 
   JOIN `Int` e
WHERE (a.i*10000 + b.i*1000 + c.i*100 + d.i*10 + e.i) <= 11322
ORDER BY 1;

/*For simplicity I work with your report as ready-to-use table*/

/*10 | 2011-01
40 | 2011-03
20 | 2011-05*/
INSERT INTO Report VALUES
(10, '2011-01'),
(40, '2011-03'),
(20, '2011-05');

/*
Select data from your report.
Also select dummy data with zero sizes, to pad the dates.
After union, we leave only data with max size value 
*/
SELECT MAX(a.size) AS size, a.mydate
FROM
(
  (
    SELECT size, dt AS mydate
    FROM Report
  ) UNION ALL
  (
    SELECT DISTINCT 0 AS size, DATE_FORMAT(dt, "%Y-%m") AS mydate
    FROM Calendar
    WHERE dt BETWEEN '2011-01-01' AND '2011-12-01'
  )
) AS a
GROUP BY a.mydate
ORDER BY a.mydate

结果是

size| mydate
------------
10  | 2011-01
0   | 2011-02
40  | 2011-03
0   | 2011-04
20  | 2011-05
0   | 2011-06
0   | 2011-07
0   | 2011-08
0   | 2011-09
0   | 2011-10
0   | 2011-11
0   | 2011-12

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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