日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

月考勤报表的TSQL查询

發布時間:2024/3/13 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 月考勤报表的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查询的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。