<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
以下演示將在下表資料中進行:
其中:id為主鍵用於表的連線;value1為需要統計的主體,如使用者等;date為記錄日期。
SELECT tmp.value1 AS `value1`, MONTH(SUBSTRING_INDEX(tmp.ct, ',', 1)) AS `month`, LENGTH(tmp.ct) - LENGTH( REPLACE (tmp.ct, ',', '') ) + 1 AS `cnt` FROM ( SELECT id, value1, GROUP_CONCAT(date_value) AS ct FROM test_year_record GROUP BY value1, INTERVAL( date_value, DATE(CONCAT('2022', '-01-01')), DATE(CONCAT('2022', '-02-01')), DATE(CONCAT('2022', '-03-01')), DATE(CONCAT('2022', '-04-01')), DATE(CONCAT('2022', '-05-01')), DATE(CONCAT('2022', '-06-01')), DATE(CONCAT('2022', '-07-01')), DATE(CONCAT('2022', '-08-01')), DATE(CONCAT('2022', '-09-01')), DATE(CONCAT('2022', '-10-01')), DATE(CONCAT('2022', '-11-01')), DATE(CONCAT('2022', '-12-01')), DATE(CONCAT('2023', '-01-01')) ) ) AS tmp JOIN test_year_record AS ot ON ot.id = tmp.id WHERE ot.value1 = 1 AND YEAR(SUBSTRING_INDEX(tmp.ct, ',', 1)) = '2022'
注:以’2022’為例,上面結論中使用了CONCAT方法進行字串拼接,方便了年份替換,可以直接替換置對應的ORM的引數等。
這個問題可以劃分為如下幾個子問題,我們可以挨個分析解決:
對於一個月份的資料可以如下判斷:
date_value >= DATE_ADD(date_value, INTERVAL - DAY(date_value) + 1 DAY) AND data_value <= LAST_DAY(data_value)
解釋一下:
DATE_ADD(date_value, INTERVAL - DAY(date_value) + 1 DAY):data_value所在月的第一天,原理為在data_value的基礎上加上-DAY(data_value)天數再+1,當然也可以使用DATE_SUB或者去YEAR和MONTH資訊再進行拼接;
LAST_DAY(date_value):data_value所在月的最後一天。
一個月的解決了,那麼多個月的無非就手寫幾個範圍就可以了(x
當然不能手寫這些範圍,一方面是很麻煩而且不好看,另一方面是會給mysql帶來過多的計算量。
那麼如何給12月進行劃分呢:
INTERVAL() 函數可以解決我們的問題:
INTERVAL( N , n 1 , n 2 , ⋯ , n 3 N,n_1,n_2,cdots,n_3 N,n1,n2,⋯,n3),其中 N N N為帶判斷是資料,後面的 n 1 ∼ n n n_1 sim n_n n1∼nn分別為各個間斷點,這個函數的返回值如下,當 N < n 1 N < n1 N<n1返回0,當 n 1 ≤ N < n 2 n_1 leq N < n_2 n1≤N<n2時返回1,當 n 2 ≤ N < n 3 n_2 leq N < n_3 n2≤N<n3時返回2,…,以此類推。
據此,我們可以給一年做一個分段:
INTERVAL( date_value, DATE(CONCAT('2022', '-01-01')), # 一月 DATE(CONCAT('2022', '-02-01')), # 二月 DATE(CONCAT('2022', '-03-01')), # 三月 DATE(CONCAT('2022', '-04-01')), # 四月 DATE(CONCAT('2022', '-05-01')), # 五月 DATE(CONCAT('2022', '-06-01')), # 六月 DATE(CONCAT('2022', '-07-01')), # 七月 DATE(CONCAT('2022', '-08-01')), # 八月 DATE(CONCAT('2022', '-09-01')), # 九月 DATE(CONCAT('2022', '-10-01')), # 十月 DATE(CONCAT('2022', '-11-01')), # 十一月 DATE(CONCAT('2022', '-12-01')), # 十二月 DATE(CONCAT('2023', '-01-01')) # 次年一月,防止次年的資料記錄進當年12月中 )
注: 這裡其實還有個問題,就是結果會返回去年的資料(0),可以像我一樣在外查詢裡面進行一個年份判斷,也可以交給java等檢測。
可以使用GROUP BY子句,以INTERVAL的值進行分組(為了保證屬於同一個value1的資料,還需要以value1進行分組)。
注:GROUP BY 子句中含有多個引數時,將會是多條這些資料都一樣的記錄分為一組。
僅僅是做了分組是不夠的,我們還需要GROUP_CONCAT()函數來獲取一個分組中的資料集。
執行完當前這步,可以獲取的結果如下:
在ct這一列中,我們獲取的資料是有規律的,比如一個日期中會有兩個"-"、兩個日期之間以",“分隔。
這裡我們選擇以”,"為標誌,統計出有多少個分隔符,再+1就得到了資料的數量。
至於實現方式,可以使用如下方式:
即
LENGTH(tmp.ct) - LENGTH(REPLACE(tmp.ct, ',', '')) + 1
取得GROUP_CONCAT獲取的第一個日期即可代表這一整個資料所在的月份。
可以使用SUBSTRING_INDEX()函數,它有三個引數,第一個引數為待片取的字串、第二個引數為分隔符、第三個引數為第幾個擷取到第幾個分隔符。
如此一來:
SUBSTRING_INDEX(tmp.ct, ',', 1)
便可以取到該日期,再使用MONTH函數即可獲取對應的月份。
我這裡是使用了一次子查詢,子查詢獲取對應的分組及GROUP_CONCAT資料,再交由外查詢進行處理。
這裡給出的方案僅僅是一種方案,也許存在著其他更快更好的解決方案但我沒有想到,在複雜問題面前一步一步獲取小資料是我習慣,這也就使得很可能出現多個巢狀著的子查詢。
到此這篇關於如何使用MySQL查詢一年中每月的記錄數的文章就介紹到這了,更多相關MySQL查詢每月記錄數內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45