月考勤报表的TSQL查询
生活随笔
收集整理的這篇文章主要介紹了
月考勤报表的TSQL查询
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
為什么80%的碼農都做不了架構師?>>> ??
最近考勤模塊中需要添加如下圖的報表:
?
我們原先的數據庫是設計經過各種簡化后如下圖所示(不考慮批準天數、銷假和請假類型等情況):
下面的SQL語句可以創建如上圖的數據表,并填充一下測試數據:
1 -- 用戶請假表 2 IF OBJECT_ID ( ' LeaveDays ' ) IS NOT NULL 3 DROP TABLE LeaveDays 4 GO 5 CREATE TABLE LeaveDays ( 6 UserCode varchar ( 8 ) NOT NULL , -- 用戶編號 7 BeginDate datetime NOT NULL , -- 請假開始時期 8 Days int DEFAULT 1 NOT NULL -- 請假天數 9 ) 10 GO 11 12 -- 添加測試數據 13 INSERT INTO LeaveDays (UserCode, BeginDate, Days) VALUES ( ' A ' , ' 2013-08-05 ' , 2 ) 14 INSERT INTO LeaveDays (UserCode, BeginDate, Days) VALUES ( ' A ' , ' 2013-08-13 ' , 1 ) 15 INSERT INTO LeaveDays (UserCode, BeginDate, Days) VALUES ( ' A ' , ' 2013-08-26 ' , 3 ) 16 17 INSERT INTO LeaveDays (UserCode, BeginDate, Days) VALUES ( ' B ' , ' 2013-08-01 ' , 1 ) 18 INSERT INTO LeaveDays (UserCode, BeginDate, Days) VALUES ( ' B ' , ' 2013-08-7 ' , 3 ) 19 20 INSERT INTO LeaveDays (UserCode, BeginDate, Days) VALUES ( ' C ' , ' 2013-08-10 ' , 4 ) 21 INSERT INTO LeaveDays (UserCode, BeginDate, Days) VALUES ( ' C ' , ' 2013-08-18 ' , 3 ) 22 INSERT INTO LeaveDays (UserCode, BeginDate, Days) VALUES ( ' C ' , ' 2013-08-24 ' , 3 ) 23 GO
現在數據庫中的數據如下圖所示:
上圖對與我們最終要構造的報表幫助不大,我們首先要查詢出來用戶在指定日期是否請假,而不是請假的開始日期和請假天數,如下圖所示:
要構造上圖的查詢需要用到數字輔助表(即自增的一個序列),關于數字輔助表的概念可閱讀經典書籍《SQL 2005技術內幕:T-SQL查詢》,生成數字輔助表的TSQL語句如下:
1 -- 數字輔助表 2 IF OBJECT_ID ( ' dbo.Nums ' ) IS NOT NULL 3 DROP TABLE dbo.Nums; 4 GO 5 CREATE TABLE dbo.Nums(n INT NOT NULL PRIMARY KEY ); 6 DECLARE @max AS INT , @rc AS INT ; 7 SET @max = 10000 ; 8 SET @rc = 1 ; 9 10 INSERT INTO Nums VALUES ( 1 ); 11 WHILE @rc * 2 <= @max 12 BEGIN 13 INSERT INTO dbo.Nums SELECT n + @rc FROM dbo.Nums; 14 SET @rc = @rc * 2 ; 15 END 16 17 INSERT INTO dbo.Nums 18 SELECT n + @rc FROM dbo.Nums WHERE n + @rc <= @max ; 19 GO然后利用數字輔助表可進行上圖的查詢:
1 WITH cte_LeaveDays AS 2 ( 3 SELECT BeginDate, BeginDate + Days - 1 AS EndDate,UserCode 4 FROM LeaveDays 5 WHERE BeginDate >= ' 2013-08-01 ' AND BeginDate < ' 2013-09-01 ' 6 ) 7 SELECT BeginDate + n - 1 AS LeaveDay, UserCode FROM cte_LeaveDays 8 JOIN Nums ON BeginDate + n - 1 <= EndDate 9 WHERE n <= 31 10 ORDER BY UserCode, LeaveDay 11最后需要使用PIVOT關鍵字進行轉列,即可生成最終報表:
1 WITH cte_LeaveDays AS 2 ( 3 SELECT BeginDate, BeginDate + Days - 1 AS EndDate,UserCode 4 FROM LeaveDays 5 WHERE BeginDate >= ' 2013-08-01 ' AND BeginDate < ' 2013-09-01 ' 6 ) 7 SELECT * FROM 8 ( 9 SELECT DAY (BeginDate + n - 1 ) AS Day , UserCode FROM cte_LeaveDays 10 JOIN Nums ON BeginDate + n - 1 <= EndDate 11 WHERE n <= 31 12 ) AS T 13 PIVOT 14 ( 15 COUNT ( Day ) FOR day IN ( 16 [ 1 ] , [ 2 ] , [ 3 ] , [ 4 ] , [ 5 ] , [ 6 ] , [ 7 ] , [ 8 ] , [ 9 ] , [ 10 ] , 17 [ 11 ] , [ 12 ] , [ 13 ] , [ 14 ] , [ 15 ] , [ 16 ] , [ 17 ] , [ 18 ] , [ 19 ] , [ 20 ] , 18 [ 21 ] , [ 22 ] , [ 23 ] , [ 24 ] , [ 25 ] , [ 26 ] , [ 27 ] , [ 28 ] , [ 29 ] , [ 30 ] , [ 31 ] ) 19 ) AS PVT 20完整代碼下載
轉載于:https://my.oschina.net/bery/blog/160144
總結
以上是生活随笔為你收集整理的月考勤报表的TSQL查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpringBoot 默认数据库连接池
- 下一篇: Bootstrap免费字体和图标网站