數(shù)據(jù)表中不存在的月份也要顯示,建議創(chuàng)建一個(gè)從1到12月份的表作為比對(duì)表。如果不方便創(chuàng)建月份比對(duì)表則可以用select 1到12的辦法來(lái)虛擬這個(gè)月份比對(duì)表,但是語(yǔ)句會(huì)有些冗長(zhǎng)。請(qǐng)參考下列寫(xiě)法:
成都創(chuàng)新互聯(lián)公司主要從事成都網(wǎng)站制作、成都做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)遼中,十多年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):18980820575
select?months.year,months.month,?
concat(ifnull(t.sumMonthNum,'0'),
'/',months.sumYearNum)?as?`月/年比`
from?
(select?*?from?
(select?year(time)?as?year,
sum(num)?as?sumYearNum?
from?abc?group?by?year(time))?years,?
(select?1?as?month?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?union?all?
select?10?union?all?
select?11?union?all?
select?12)?months)?months?left?join?
(select?year(time)?as?year,
month(time)?as?month,
sum(num)?as?sumMonthNum?
from?abc?group?by?year(time),month(time))?t?
on?months.month=t.month?
order?by?months.year,months.month;
實(shí)驗(yàn)截圖如下:
源表數(shù)據(jù)
SQL代碼及運(yùn)行結(jié)果
比較簡(jiǎn)單直接一點(diǎn)的方法就是判斷這個(gè)月份是不是1、4、7、10這4個(gè)月份的有一個(gè),如果是,就是季度的第一個(gè)月。
判斷條件是
if 月份 in (1,4,7,10) then 實(shí)現(xiàn)。
如果你是想判斷月份是哪個(gè)季度的第一個(gè)月,用case when語(yǔ)句也就可以實(shí)現(xiàn)了
第一種方法用left join,?把月份顯示出來(lái),沒(méi)有相應(yīng)月份的時(shí)候,也會(huì)顯示月份對(duì)應(yīng)的列,但是值為空
第二種方法用臨時(shí)表,建立2個(gè)字段,一個(gè)字段用來(lái)標(biāo)注月份,另外一個(gè)字段標(biāo)注統(tǒng)計(jì)值,先把12個(gè)月全部寫(xiě)進(jìn)去,然后用指針對(duì)12個(gè)月進(jìn)行統(tǒng)計(jì),把結(jié)果填入到對(duì)應(yīng)月份的統(tǒng)計(jì)結(jié)果中,如果為空就填0
?? 在統(tǒng)計(jì)數(shù)據(jù)的需求中很容易出現(xiàn)按照天來(lái)統(tǒng)計(jì)數(shù)據(jù)的場(chǎng)景,有時(shí)某一列的維度在那天并沒(méi)有產(chǎn)生數(shù)據(jù),但是又沒(méi)有一列是可以確保每天都是有數(shù)據(jù)的,由于mysql中并沒(méi)有fulljoin這樣的關(guān)聯(lián)方式,在這種情況下關(guān)聯(lián)查詢(xún)就有些費(fèi)勁,解決的辦法也是多種多樣,畢竟條條大路通羅馬嘛,其他的就不說(shuō)了,這里介紹一種相對(duì)方便的方法。
?? 產(chǎn)生一個(gè)足夠長(zhǎng)的時(shí)間列,這個(gè)列要能夠包含想要統(tǒng)計(jì)的所有日期。這個(gè)思路的實(shí)現(xiàn)很泛,可以創(chuàng)建一個(gè)日期的臨時(shí)表,然后將想要查的日期插入,拋開(kāi)創(chuàng)建表比較麻煩之外,一般在職能比較完善的公司,生產(chǎn)環(huán)境創(chuàng)建表或者修改數(shù)據(jù)是需要交給專(zhuān)門(mén)的DBA去操作的,各種流程。。。相對(duì)這個(gè)較簡(jiǎn)單的一種方式就是創(chuàng)建存儲(chǔ)過(guò)程,然后產(chǎn)生時(shí)間列,這也是一種解決辦法。
?? 我的思路是先定義一個(gè)時(shí)間變量并初始化,然后和某個(gè)數(shù)據(jù)足夠多的表關(guān)聯(lián)查詢(xún)獲取時(shí)間列,這個(gè)表一般選取某張要查的表即可,數(shù)據(jù)條數(shù)只要超過(guò)需要查詢(xún)的條數(shù)即可,足夠即可,太多就是浪費(fèi),降低查詢(xún)效率。
?? 比如說(shuō)我要查詢(xún)2018-01-10到2018-01-20每天的數(shù)據(jù),那么就可以寫(xiě)成
?? 其中,cdate是我定義的一個(gè)時(shí)間變量,初始化的值是2018-01-09,因?yàn)樵谕饷婺遣糠謭?zhí)行之后值已經(jīng)加1了,已經(jīng)不是2018-01-10了;data_t是我關(guān)聯(lián)產(chǎn)生記錄的實(shí)體表,這個(gè)表只有一個(gè)要求,就是能幫我們產(chǎn)生足夠的時(shí)間列條數(shù),后面的limit 15是幫助我產(chǎn)生15條時(shí)間記錄,可以換成其他條件;生成的t0其實(shí)就是15條全為2018-01-09的記錄,外面的查詢(xún)?cè)诿繏呙枰粭lt0的記錄就會(huì)加1天,這樣就會(huì)產(chǎn)生連續(xù)的時(shí)間列;WHERE后面是最終查詢(xún)的截止條件,換成其他的也可以。
關(guān)聯(lián)其他表舉例:
查詢(xún)從2018-01-10到當(dāng)前日期每天的統(tǒng)計(jì)數(shù)據(jù)
??通過(guò)上面的例子我想大部分人應(yīng)該可以靈活變化了,比如查詢(xún)多少天內(nèi)每天的統(tǒng)計(jì)數(shù)據(jù),某幾個(gè)月內(nèi)每月的統(tǒng)計(jì)數(shù)據(jù)等等,通過(guò)修改上面給的例子里面的sql完全可以做到,可以說(shuō)這種思路就是個(gè)‘萬(wàn)能模板’,希望本文能夠幫到大家。
里上圖 表 aaa, ?要按月份查找,a 出現(xiàn)的次數(shù),代碼如下
SELECT
CAST(YEAR(rq)??as?varchar)?+?'-'?+?CAST(MONTH(rq)??as??varchar)??AS??date,
count(*)??AS?'次數(shù)'
FROM?aaa
where?a="a"
GROUP?BY
CAST(YEAR(rq)??as?varchar)?+?'-'?+?CAST(MONTH(rq)??as??varchar);
結(jié)果如下圖,看看是不是你要的
select DATE_FORMAT(來(lái)電時(shí)間,'%Y-%m') as 月, 問(wèn)題類(lèi)別 , count(1) as 數(shù)量 from
( select 來(lái)電時(shí)間, 問(wèn)題類(lèi)別 from mytable where 問(wèn)題類(lèi)別 = '農(nóng)村用水投訴' ) tmptable
group by DATE_FORMAT(來(lái)電時(shí)間,'%Y-%m') ,問(wèn)題類(lèi)別 ORDER BY 月 ASC;