SELECT month(dateofappointment), COUNT(*) 'NumberOfAppointments'
FROM appointment
WHERE YEAR(dateofappointment) = '2016'
GROUP BY MONTH(dateofappointment)
這顯示我所有月份,但十二月不存在,因爲那一年沒有任何約會。我如何顯示12月爲0?每月約會,12月失蹤?
SELECT month(dateofappointment), COUNT(*) 'NumberOfAppointments'
FROM appointment
WHERE YEAR(dateofappointment) = '2016'
GROUP BY MONTH(dateofappointment)
這顯示我所有月份,但十二月不存在,因爲那一年沒有任何約會。我如何顯示12月爲0?每月約會,12月失蹤?
要解決這些類型的查詢往往有助於將它們表達爲一系列要求,這可以使其更容易解決。
當結果沒有達到理想的效果,請用新的要求您的要求語句識別它們,然後再試一次:
在我看來,現在你有2個要求:
Ø k因此這是一個冗長的內容,但是你看到你在查詢中缺少的是一個聲明,它定義了'2016年每個月的1行'所以你需要先手動或者通過遞歸構建記錄集。
的MySQL目前不支持遞歸公用表表達式,這在許多其它RDBMS
一個簡單的概念,但是如果MySQL不支持遞歸,我們有什麼選擇?這裏有一些其他的嘗試上SO:
這聽起來有點劈的,但你可以在你的數據庫中有更多使用任何表比12行,並有一個自動遞增的領域,哦,並被播種開始在1(或以下)。忘記這是否是正確的還是錯誤的,它會工作:
SELECT Id
FROM LogEvent -- An arbitrary table that I know has records starting from 1
WHERE Id BETWEEN 1 AND 12
所以這是哈克,但我們可以實現一個行計數功能,使我們可以使用任何表有12個或更多的行,而不管的id或播種,偷來的:MySQL get row number on select - Answer by Mike Cialowicz
SET @rank=0;
SELECT @rank:[email protected]+1 AS rank
FROM orders
WHERE rank <= 12
現在,我們可以從工會這個結果缺少的行設置爲原始查詢,或者使用一個連接操作。首先使用union的解決方案
使用UNION ALL將缺失的行注入到記錄集是很常見的,因爲它將預期結果查詢從異常或默認結果中分離出來。有時,這句法使得它更容易解釋的預期操作
SET @rank = 0;
SELECT month(dateofappointment) as Month, COUNT(*) 'NumberOfAppointments'
FROM appointment
WHERE YEAR(dateofappointment) = '2016'
GROUP BY MONTH(dateofappointment)
UNION ALL
SELECT rank, 0
FROM (
SELECT @rank:[email protected]+1 AS rank
FROM rows
WHERE @rank < 12
) months
WHERE NOT EXISTS (SELECT dateofappointment
FROM appointment
WHERE YEAR(dateofappointment) = '2016' AND MONTH(dateofappointment) = months.rank)
ORDER BY Month
但它使一個醜陋查詢。您也可以加入月數查詢,並在約會次數上加入左連接,但這裏的意圖很難識別。
SET @rank = 0;
SELECT months.rank, COUNT(appointment.dateofappointment)
FROM (
SELECT @rank:[email protected]+1 AS rank
FROM rows
WHERE @rank < 12
) months
LEFT OUTER JOIN appointment ON months.rank = Month(appointment.dateofappointment) AND YEAR(dateofappointment) = '2016'
GROUP BY months.rank
I have saved these queries into a SqlFiddle so you can see the results: http://sqlfiddle.com/#!9/99d485/4
正如我上面指出的那樣,這是在MS SQL和Oracle RDBMS,在這裏我們可以動態地通過遞歸公用表表達式(CTE的)對於生成值序列瑣碎這裏的家庭玩家是MS SQL Server 2014中的一個實現。該示例稍微更加演化,使用from和from date來動態過濾結果
-- Dynamic MS SQL Example using recursive CTE
DECLARE @FromDate Date = '2016-01-01'
DECLARE @ToDate Date = '2016-12-31'
;
WITH Months(Year, Month, Date) AS
(
SELECT Year(@FromDate), Month(@FromDate), @FromDate
UNION ALL
SELECT Year(NextMonth.Date), Month(NextMonth.Date), NextMonth.Date
FROM Months
CROSS APPLY (SELECT DateAdd(m, 1, Date) Date) NextMonth
WHERE NextMonth.Date < @ToDate
)
SELECT Months.Year, Months.Month, COUNT(*) as 'NumberOfAppointments'
FROM Months
LEFT OUTER JOIN appointment ON Year(dateofappointment) = Months.Year AND Month(dateofappointment) = Months.Month
GROUP BY Months.Year, Months.Month
我使用union實現了您的第一個查詢,並且我仍然得到了相同的結果:12月份丟失了。 – maia
如果你自己運行rownunber例子(所以嵌套查詢),你會得到12行?我有這些例子都運行在MySQL與預期的結果。我會嘗試設置一個sqlfiddle –
@maia看到這個小提琴http://sqlfiddle.com/#!9/99d485/4我會編輯這個答案以及包括輸出 –