-- 查找表tb_name中所有每月最后一天的記錄
SELECT * FROM tb_name WHERE date = DATEADD(mm, DATEDIFF(mm, -1, dateCol), -1)
1、DATEDIFF(mm, -1, dateCol)
定義:DATEDIFF() 函數返回兩個日期之間的時間。
語法:DATEDIFF(datepart,startdate,enddate)
這里startdate位置0表示1990-01-31,-1表示1899-12-31,該函數表示時間列距離'1899-12-31'相差多少個月
為什么31號而不是01號呢?
-- 執行下語句,最后一個字段顯示1
SELECT *, DATEDIFF(day, -1, '1900-01-01') FROM tb_name
-- 執行下語句,最后一個字段顯示31
SELECT *, DATEDIFF(day, -1, '1900-01-31') FROM tb_name
所以可以肯定的是DATE函數使用數字表示的是31號
2、DATEADD(mm, DATEDIFF(mm, -1, dateCol), -1)
定義:DATEADD() 函數在日期中添加或減去指定的時間間隔。
語法:DATEADD(datepart,number,date)
前面已經說了-1表示1899-12-31,加上時間列距離'1899-12-31'相差的月數,即表示時間列當月的最后一天
3、分組(分區)最后一條記錄,因為之前說到的語句如果要統計這個月為止,但未到月底自然沒有數據,所以要統計每月最后一條數據。
-- 查找表tb_name中groupCol列分組orderCol列排序下每種分組的最后一條記錄
SELECT * FROM ( SELECT ROW_NUMBER() OVER(PARTITION BY groupCol ORDER BY orderCol DESC) AS Row_Index, * FROM tb_name) t WHERE t.Row_Index=1
-- 實際應用:查找表tb_name中每月(yyyy-MM)分組最后一條記錄
SELECT CONVERT(varchar(7), DATE, 120) AS month, * FROM ( SELECT ROW_NUMBER() OVER(PARTITION BY CONVERT(varchar(7), DATE, 120) ORDER BY date DESC) AS Row_Index, * FROM tb_name) t WHERE t.Row_Index=1
簡單解釋下:
ROW_NUMBER( ) OVER 編號
partition by 分組(分區)
order by 排序