今天在工作中遇到了一個很實際的問題,客戶在OA介面的員工休假中間表中提供了連續時間段的休假記錄,例如: 張三,2018-12-1 ~2018-12-31 ,病假,31天。這樣帶來的問題是,如果我需要統計張三從12月1號到12月15號的休假天數,單從這一整條連續記錄是無法統計的。這時候就需要我們將一條 ...
今天在工作中遇到了一個很實際的問題,客戶在OA介面的員工休假中間表中提供了連續時間段的休假記錄,例如: 張三,2018-12-1 ~2018-12-31 ,病假,31天。這樣帶來的問題是,如果我需要統計張三從12月1號到12月15號的休假天數,單從這一整條連續記錄是無法統計的。這時候就需要我們將一條長記錄進行拆分。
這裡記錄下我自己的思路:
1:利用系統表得到0-2047的序列 ,2048*2048絕對夠用了吧
SELECT sv.number AS n FROM MASTER.dbo.spt_values AS sv WHERE sv.[type]='P'
結果如圖:
2:利用CROSS APPLY 得到最終序列(從1開始,最後一行是2048*2048)
WITH t1 AS (SELECT sv.number AS n FROM MASTER.dbo.spt_values AS sv WHERE sv.[type]='P'), t2 AS ( SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rid FROM t1 AS a CROSS APPLY t1 AS b) ----------------- SELECT *FROM t2
結果如圖
你千萬別告訴我400多萬都不夠你拆的啊,小心我揍你
3:奉上完整代碼
DECLARE @begindate DATE =CAST('2017-12-1' AS date) DECLARE @enddate DATE =CAST('2017-12-31' AS date) BEGIN WITH t1 AS (SELECT sv.number AS n FROM MASTER.dbo.spt_values AS sv WHERE sv.[type]='P'), t2 AS ( SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rid FROM t1 AS a CROSS APPLY t1 AS b) ----------------- --SELECT *FROM t2 SELECT DATEADD(DAY,t2.rid-1,@begindate) as date FROM t2 WHERE t2.rid BETWEEN -1 AND (DATEDIFF(DAY,@begindate,@enddate)+1) END
PS:因為序列從1開始,用Dateadd函數我需要從0天開始加起(作為第一天),因此註意下上述代碼的-1 和+1的作用。
效果如圖:
最後:
關於With 關鍵字、row_nunber()over()開窗函數 以及cross apply請您自行腦補學習,以免一知半解