關於SQLServer2005的學習筆記——生日問題
主要的邏輯難點第一個是關於閏月尾天的計算,第二個是判斷本年度生日是否已過
本文給出了三種解決辦法,
第一種是最常用的解決辦法,即常用的SQL語法,不過看起來比較複雜,適合環境為SQLServer2000以上
第二種是採用函式的方法,把對日期的邏輯處理放到函式中,呼叫起來會簡約一下,適合環境為SQLServer2000以上
第三種是採用CTE的方法,用CTE來封裝判斷邏輯,適合環境為SQLServer2005以上
--建立表和資料 CREATE TABLE employees ( name VARCHAR(50), birthday DATETIME ) INSERT INTO employees VALUES('WBQ','1948-12-08'); INSERT INTO employees VALUES('CZH','1952-02-19'); INSERT INTO employees VALUES('LB','1963-08-30'); INSERT INTO employees VALUES('YLL','1937-09-19'); INSERT INTO employees VALUES('YGQ','1955-03-04'); INSERT INTO employees VALUES('CHH','1963-07-02'); INSERT INTO employees VALUES('SWG','1960-05-29'); INSERT INTO employees VALUES('HW','1958-01-01'); INSERT INTO employees VALUES('YY','1972-02-29'); INSERT INTO employees VALUES('LM','1999-02-08'); INSERT INTO employees VALUES('ZY','1972-06-09'); INSERT INTO employees VALUES('WZH','1999-02-28'); SELECT name,birthday FROM employees |
--普通的SQL實現 SELECT name, birthday, GETDATE() getdate, CONVERT(VARCHAR(10),GETDATE(),120) todayVarchar, CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),120)) todayDateTime, DATEDIFF(YY,birthday,GETDATE()) DateBetween, DATEADD(YY,DATEDIFF(YY,birthday,GETDATE()),birthday) ThisBirthday, DATEADD(YY,DATEDIFF(YY,birthday,GETDATE())+1,birthday) NextBirthday, CASE WHEN CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),120))>DATEADD(YY,DATEDIFF(YY,birthday,GETDATE()),birthday) THEN DATEADD(YY,DATEDIFF(YY,birthday,GETDATE())+1,birthday) ELSE DATEADD(YY,DATEDIFF(YY,birthday,GETDATE()),birthday) END newBirthdayStandard, CASE WHEN CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),120))>DATEADD(YY,DATEDIFF(YY,birthday,GETDATE()),birthday) THEN DATEADD(YY,DATEDIFF(YY,birthday,GETDATE())+1,birthday)+ CASE WHEN DAY(birthday)=29 AND DAY(DATEADD(YY,DATEDIFF(YY,birthday,GETDATE())+1,birthday))=28 THEN 1 ELSE 0 END ELSE DATEADD(YY,DATEDIFF(YY,birthday,GETDATE()),birthday) + CASE WHEN DAY(birthday)=29 AND DAY(DATEADD(YY,DATEDIFF(YY,birthday,GETDATE()),birthday))=28 THEN 1 ELSE 0 END END newBirthdayForeign FROM employees |
--使用函式來實現 CREATE FUNCTION GetBirthday(@birthday DATETIME,@flag INT) RETURNS DATETIME AS BEGIN DECLARE @BirthdayRet DATETIME,@BirthdayThis DATETIME,@BirthdayNext DATETIME,@today DATETIME,@dateBetween INT SET @today=CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),120)) SET @dateBetween=DATEDIFF(YY,@birthday,GETDATE()) SET @BirthdayThis=DATEADD(YY,@DateBetween,@birthday) SET @BirthdayNext=DATEADD(YY,@DateBetween+1,@birthday) IF @flag=1 --2月29日的生日計算為2月28日 BEGIN IF @today>@BirthdayThis SET @BirthdayRet=@BirthdayNext ELSE SET @BirthdayRet=@BirthdayThis END ELSE --2月29日的生日計算為3月1日 BEGIN IF @today>@BirthdayThis IF DAY(@birthday)=29 AND DAY(@BirthdayNext)=28 SET @BirthdayRet=@BirthdayNext+1 ELSE SET @BirthdayRet=@BirthdayNext ELSE IF DAY(@birthday)=29 AND DAY(@BirthdayThis)=28 SET @BirthdayRet=@BirthdayThis+1 ELSE SET @BirthdayRet=@BirthdayThis END RETURN @BirthdayRet END
SELECT name,birthday,dbo.GetBirthday(birthday,0),dbo.GetBirthday(birthday,1) FROM employees |
--透過CTE來實現 WITH DateBetween AS ( SELECT name, birthday, GETDATE() getdate, CONVERT(VARCHAR(10),GETDATE(),120) todayVarchar, CONVERT(DATETIME,CONVERT(VARCHAR(10),GETDATE(),120)) todayDateTime, DATEDIFF(YY,birthday,GETDATE()) DateBetween FROM employees ), DateBirthdayThisAndNext AS ( SELECT name,birthday,getdate,todaydatetime,datebetween, DATEADD(YY,DateBetween,birthday) AS DateCur, DATEADD(YY,DateBetween+1,birthday) AS DateNext FROM DateBetween ), DateBirthdayThisAndNextForeign AS ( SELECT name,birthday,todaydatetime, DateCur,DateNext, DateCur+CASE WHEN DAY(birthday)=29 AND DAY(DateCur)=28 THEN 1 ELSE 0 END AS DateCurForeign, DateNext+CASE WHEN DAY(birthday)=29 AND DAY(DateNext)=28 THEN 1 ELSE 0 END AS DateNextForeign FROM DateBirthdayThisAndNext ), DateBirthday AS ( SELECT name,birthday, CASE WHEN DateCurForeign>=todaydatetime THEN DateCurForeign ELSE DateNextForeign END AS birthDayForeign, CASE WHEN DateCur>=todaydatetime THEN DateCur ELSE DateNext END AS birthDayStandard FROM DateBirthdayThisAndNextForeign ) SELECT name,birthday,birthDayForeign,birthDayStandard FROM DateBirthday |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/6517/viewspace-627396/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 關於SQLServer2005的學習筆記——多觸發器執行問題SQLServer筆記觸發器
- 關於SQLServer2005的學習筆記(一)——前言SQLServer筆記
- 關於SQLServer2005的學習筆記——子查詢SQLServer筆記
- 關於SQLServer2005的學習筆記——分析函式SQLServer筆記函式
- 關於SQLServer2005的學習筆記——XML的處理SQLServer筆記XML
- 關於SQLServer2005的學習筆記——樹形結構SQLServer筆記
- 關於SQLServer2005的學習筆記——SQL查詢解析步驟SQLServer筆記
- 關於SQLServer2005的學習筆記——自定義分組的實現SQLServer筆記
- 關於SQLServer2005的學習筆記——異常捕獲及處理SQLServer筆記
- 【學習筆記】關於Freemark程式碼輸出值的問題筆記
- 關於SQLServer2005的學習筆記——臨時表、表變數和CTESQLServer筆記變數
- 關於http(自己的學習筆記)HTTP筆記
- 關於SQLServer2005的學習筆記——CTE遞迴和模擬測試資料SQLServer筆記遞迴
- swift 關於 toolbar 學習筆記Swift筆記
- 關於SQLServer2005的學習筆記——約束、Check、觸發器的執行順序SQLServer筆記觸發器
- Myth 關於Git的學習筆記Git筆記
- Android學習筆記---關於獲取極光IDgetRegistrationID為空的問題Android筆記
- 關於EJB的學習曲線的問題
- Hbase學習筆記問題總結筆記
- 關於django reset_framework學習之路的筆記DjangoFramework筆記
- 學習本站Laravel教程中遇到的問題筆記Laravel筆記
- [個人筆記] 關於linux的常見問題合集筆記Linux
- 強化學習-學習筆記11 | 解決高估問題強化學習筆記
- 解答關於學習前端的一些問題前端
- 關於網路安全的逆向分析方向學習筆記筆記
- XML學習筆記(一):關於字元編碼的理解XML筆記字元
- 關於學習java中的按位取反(~)的問題Java
- 關於原始碼的學習的一些問題原始碼
- 【R語言學習筆記】若干排序問題R語言筆記排序
- GoldenGate學習筆記(9)_常見問題Go筆記
- 機器學習筆記009 | 關於分類問題的預測機器學習筆記
- 關於學習效率問題,一點點心得
- Android學習筆記——關於onConfigurationChangedAndroid筆記
- 關於機器視覺學習路線的問題?視覺
- php 學習筆記之關於時區的那點事PHP筆記
- 【演算法學習筆記】生成樹問題探究演算法筆記
- 《L01 Laravel 教程》 學習筆記 - 部署問題Laravel筆記
- numpy的學習筆記\pandas學習筆記筆記