SQL語法計算 統計時間日期

前言:
無論程序設計者或系統發開者,大多習慣透過程序語言,來執行資料運算以及日期期間的統計,然而如此一來,不僅會增加系統的負荷,也必須花較長的時間運算,因此無法立即呈現前端資料,此外,若資料量過大,也較容易發生當機的狀況,此時,如果能善加利用SQL語法,不僅可降低程序的負荷,亦能快速找到所需要的日期區間或統計差。

本文:
就程序開發而言,不管是系統後端,或是統計報表,往往必須運用各種不同的資料來源,大量的交互運算,不僅設計者必須耗費心思開發,使用者也得花上些許時間來等候資料呈現,而且隨著資料量愈大、運算愈趨複雜,當機事件與網頁無法迴應等情況更是層出不窮。

大部分企業的程序開發,皆採用許多程序計算語言與邏輯,光1個月份的統計設計,可能就有將近千行的程序碼,以致日常所需的日期差與前後月份等統計,即佔據大半的系統統計資源。以財務人員每個月底的統計報表產出爲例,由於所擷取的資料來源廣泛,可能是ERP、CRM等資料庫,透過不斷的演算、轉換、查詢、統計、四捨五入等過程,就足以讓系統運作的負荷,持續維持在高點之上。

有監於此,建議相關程序開發人員可善用資料庫的語法,再結合部分程序碼,不僅能有效減輕系統的負荷,亦讓資料庫不只具備儲存資料的功能,還可有效分散運算,亦即一部分交由資料庫運算,另一部分則由系統程序統計,如此一來,不僅提升系統的執行效能,亦可加快計算時間,一舉兩得豈不皆大歡喜!

因此,本文將介紹目前較常用日期統計方法,以供讀者參考、利用;再者,程序開發者亦可透過SQL管理界面執行查詢作業,檢視目前統計出來的資料正確與否,亦可加深SQL語法的記憶力。

計算每月的第1天

通常設計者會以當月份的第1天到當天的日期區間,進行差異性統計,或是擷取這段時間內的資料,如果其間的資料量與運算量較多,往往造成運算速度緩慢,因此可先透過SQL語法計算日期,之後再套用到程序碼當中,如此不僅可提高程序的執行效能,亦可快速取得計算結果。

舉例來說,若要找出當月份第1天,輸入:SELECT DATEADD(mm, DATEDIFF(mm,0,getdate()), 0),即可獲得所需要的日期。
71529-1-fy155.jpg

另外,在SQL語法中,若無添加日期顯示特別設定,其產生的結果將包含時/分/秒等單位,即「2007-11-01 00:00:00.000」,系統會自動帶出以毫秒爲最小單位的時間,雖然呈現的資料相當詳盡,不過就某些使用情況而言,卻太過累贅,此時可藉由程序的輔助,將該數據修正爲「2007-11-01」。

計算哪裏天是本週的星期一

此一運算大多用於某一系統執行行事曆之際,因此,可能因計算機系統設定年月的不同,而造成系統判斷錯誤,透過以下語法,則可計算出正確的日期。例如:今天爲2007/11/04星期日,其語法爲:SELECT DATEADD(wk, DATEDIFF(wk,0,getdate()), 0),得到的結果(亦即當週的星期一)應爲5日。
71529-2-fy155.jpg

設計者必須注意的是,系統會以星期日作爲每週的第1天,所以上述所得到的結果爲「2007-11-05 00:00:00.000」,而非「2007-10-29 00:00:00.000」。

計算每季的第1天

關於每季的統計,以財務部門執行每季報表與統計時最常用,一般設計是以「寫死的方式」進行,使用上較不具彈性,這個部分我們同樣可以透過SQL語法來計算:SELECT DATEADD(qq, DATEDIFF(qq,0,getdate()), 0),假設今天日期爲2007-11-04,本季第1天則爲2007-10-01。
71529-3-fy155.jpg

計算上個月的最後1天

SQL Server對於時間的計算,可細算到3毫秒之差,所以我們可趁此減去3毫秒,來實際驗證一下。假設今天爲2007-11-04 ,欲查詢上個月最後1天,可輸入:SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)),計算出來的結果顯示爲「2007-10-31 23:59:59.997」。
71529-4-fy155.jpg

若要查詢今年最後1天日期爲何,輸入:SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0)),便可得知日期時間爲「2007-11-30 23:59:59.997」。
71529-5-fy155.jpg

查詢本月第1個星期一

若要查詢本月第1個星期一的日期,可輸入:SELECT DATEADD(wk, DATEDIFF(wk,0,dateadd(dd,6-datepart(day,getdate()),getdate())), 0),其語法中的wk爲星期的表示方式。
71529-6-fy155.jpg
如果希望計算結果僅出現日期,無須顯示毫秒,甚至希望呈現各種不同的日期型態,可透過下列幾種語法獲得需要的結果。

去時/分/秒的方法
若要完整呈現時/分/秒,輸入:declare @ datetime set @ = getdate() --'2003-7-1 10:00:00' 後按下Enter,再輸入SELECT @,即可獲得當下時/分/秒的時間。
71529-7-fy155.jpg

如果要去除時/分/秒,按下Enter後輸入「,DATEADD(day, DATEDIFF(day,0,@), 0)」點執行鍵,便可呈現2種時間表達方式,一是有時/分/秒,二是無時/分/秒的結果。
71529-8-fy155.jpg

查詢當天星期或日期
可輸入:select datename(weekday,getdate())查詢當天爲星期幾,此外,也可以將weekday改成「dd」,顯示當天日期爲幾號,同理,輸入「mm」爲顯示月份,輸入「yyyy」則顯示年份。

71529-9-fy155.jpg
圖說:查詢當天爲星期幾。

71529-10-fy155.jpg
圖說:查詢當天日期爲幾號。

71529-11-fy155.jpg
圖說:查詢當月。

71529-12-fy155.jpg
圖說:查詢今年。

查詢某月總天數
若要查詢某月份總天數,可利用語法輸入欲查詢的月份,甚至可透過參數設定,來銜接SQL語法中的「5」,其輸入方式爲:declare @m int,接著按下Enter後輸入set @m=5 --即可設定月份,然後再按下Enter,輸入select datediff(day,'2003-'+cast(@m as varchar)+'-15' ,'2003-'+cast(@m+1 as varchar)+'-15')。

若要查詢當月總天數,輸入select datediff(day,cast(month(GetDate()) as varchar)+'-'+cast(month(GetDate()) as varchar)+'-15' ,cast(month(GetDate()) as varchar)+'-'+cast(month(GetDate())+1 as varchar)+'-15'),便可查詢當月天數,或者也可利用DAY來計算,其語法爲:SELECT Day(dateadd(ms,-3,DATEADD(mm, DATEDIFF(m,0,getdate())+1, 0))),至於結果是一樣的。

71529-13-fy155.jpg
圖說:查詢某月總天數。

71529-14-fy155.jpg
圖說:查詢當月總天數。

71529-15-fy155.jpg
圖說:利用DAY查詢當月總天數。

上述各類日期語法還有很多不同的運用,甚至修改年、月、日,就能得到不同的日期呈現方式,這些都是SQL語法的特點,使用者可透過上述語法,自行修改與測試,只要多加練習,不僅能對語法應用更加熟悉,同時也有助提升系統運算效率。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章