2017-10-09 113 views
0

我被困在試圖返回過去12個月的總和,當月和年用作輸入。選擇前12個月按月和年輸入

根據輸入我可以得到一整年(從1月到12月),但是我之後說的是如果我輸入('08','2017')它會計算08/2016-08的總計/ 2017年。

我知道我將不得不添加另一個輸入併爲其指定一個值,例如IN targetMonth int,但我不確定如何去處理INTERVAL。

'date_admitted'列的值爲'2010-01-30'的形式。本質上,生成的表如下所示:

Month Total % 
08 2016 10 16 
09 2016 10 16 
10 2016 10 16 
11 2016 10 16 
12 2016 10 16 
01 2017 10 16 
    etc etc etc 

我的繼承人了整整一年

DROP PROCEDURE IF EXISTS YrReport; 
DELIMITER // 
CREATE PROCEDURE YrReport( 
IN targetYear int) 
BEGIN 
SELECT DATE_FORMAT(date_admitted, '%m') 
AS Month, 
COUNT(id) 
AS Total, 
ROUND(COUNT(id)/(SELECT COUNT(id) FROM 
accessions 
WHERE year(date_admitted) = targetYear)*100) 
AS '%' 
FROM accessions 
WHERE year(date_admitted) = targetYear 
GROUP BY DATE_FORMAT(date_admitted, '%Y%m'); 
END // 
DELIMITER ; 
+1

請參閱:[爲什麼我應該爲我認爲是非常簡單的SQL查詢提供一個MCVE?](https://meta.stackoverflow.com/questions/333952/why-should-i-provide-an -mcve-for-what-seem-to-what-seems-a-very-simple-sql-query) – Strawberry

+0

是將INTERVAL語句添加到WHERE子句中的方式嗎?我有一個去它,但我認爲它不會工作,因爲我的輸入是int而不是日期? – Blake

回答

0

我沒有考慮你寫的整個代碼,但似乎你可以通過改變你的WHERE條件解決您的問題。讓我們假設你有第二個參數的存儲過程,

.... 
IN targetMonth int) 

,那麼你可以通過

WHERE ((YEAR(date_admitted) = targetYear) AND 
     (MONTH(date_admitted) < targetMonth)) OR 
     ((YEAR(date_admitted) = (targetYear - 1)) AND 
     (MONTH(date_admitted) >= targetMonth)) 

更換

WHERE year(date_admitted) = targetYear 

和改變其他WHERE條件以類似的方式,如果必要。回到你的例子,這將選擇08/2016(含)至07/2017(含),這是12個月。如果您想要選擇09/201608/2017,則可以調整代碼。

與其他解決方案相比,我認爲這將運行得非常快,但只有在您想要包含一年的情況下才能正常工作。例如,您無法輕易調整該代碼以包含13個月。

+0

@Downvoter你能否詳細說明這個答案有什麼問題? – Binarus

+0

感謝堆解決了我的問題! – Blake

0

這裏calcuating代碼是你需要的東西:

如果你有一個數字的一​​年,例如2016,您可以使用像這樣的表達式來檢索該日曆中包含date_admitted的所有行。

WHERE date_admitted >= MAKEDATE(year, 1) 
    AND date_admitted < MAKEDATE(year, 1) + INTERVAL 1 YEAR 

如果你有一些郵戳一天,你想要檢索的十二個整月的那一天(未年至今)之前的數據,做到這一點。

WHERE date_admitted >= LAST_DAY(datestamp) + INTERVAL 1 DAY - INTERVAL 13 MONTH 
    AND date_admitted < LAST_DAY(datestamp) + INTERVAL 1 DAY - INTERVAL 1 MONTH 

這對於當前日期尤其有用。

WHERE date_admitted >= LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 13 MONTH 
    AND date_admitted < LAST_DAY(CURDATE()) + INTERVAL 1 DAY - INTERVAL 1 MONTH 

如果您每月需要組做這樣的事情

SELECT SUM(something), COUNT(*), LAST_DAY(date_admitted) month_ending 
    FROM someTable 
    GROUP BY LAST_DAY(date_admitted) 

採用MySQL date arithmetic可以得到一個有點冗長。但它可以讓你做很多日期過濾和分組精確。

一個習慣是這樣的。包含日期戳。這個月的第一天是

LAST_DAY(datestamp) + INTERVAL 1 DAY - INTERVAL 1 MONTH 
相關問題