簡體   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