2013-08-25 14 views
0

我正在實施用於監視性能的點跟蹤系統。員工的目標是根據需要擁有儘可能少的積分。有一個積分制度,允許員工通過在各個時間段內表現更好而減少積分。表演30天內積分減少1分,未積分達到60天時積分減少2分,無事故時積分達到90天積分減少4分。他們無法積累負值,並且從最早的日期到最新的日期分數下降。下面的示例表格是已導入到SQL Server 2012數據庫中的現有表格的表示形式。使用DATEDIFF和記錄值更新的遞歸SUM

Employee Points Date Previous Note 
Smith, Joe 0.25 3/21/2013  
Smith, Joe 1  4/1/2013   
Smith, Joe 0.25 5/6/2013   
Smith, Joe 0.5  5/8/2013   
Smith, Joe 1  7/10/2013  
Jones, Tom 1  4/10/2013  
Jones, Tom 1  4/18/2013  
Jones, Tom 0.5  4/22/2013  
Jones, Tom 2  6/25/2013  
Jones, Tom 0.25 7/26/2013  
Jones, Tom 0.25 7/28/2013  

因爲動態數據使用,將多個來源,如C#,Excel和電子郵件的,有必要建立確定性的功能,併產生或者是表或視圖被更新,將顯示類似的東西以下。下面的例子是,報告看起來是在2013年5月18日推出的。每個員工都會得到1分。因爲Joe的第一個點是.25,它將被設置爲0,而下一個1.00的點將被剩下的0.75減少到0.25的值。因爲湯姆有1分滿分作爲他的第一分,所以會從1分中減去,結果在那個日期得0分。在更新Point值之前,函數還應該記錄Points列的先前值。該函數應該提供關於更改點的原因的註釋,在註釋字段中日期會很好,但NoteDate的單獨列可以包含日期。該函數可以在INSERT/UPDATE觸發器上運行,因爲日常使用量非常低。它應該檢查當前日期和最後一個點日期。

Employee Points Date Previous Note 
Smith, Joe 0.00 3/21/2013 0.25 Rolled Off by System - 30 Day Policy 05/01/2013 
Smith, Joe 0.25 4/1/2013 1.00 Rolled Off by System - 30 Day Policy 05/01/2013 
Smith, Joe 0.25 5/6/2013   
Smith, Joe 0.50 5/8/2013   
Jones, Tom 0.00 4/10/2013 1.00 Rolled Off by System - 30 Day Policy 05/22/2013 
Jones, Tom 1.00 4/18/2013  
Jones, Tom 0.50 4/22/2013  

到08/24/2013今天的日期,結果應該反映出下列內容。喬總共有0分,湯姆總共有2分,到28日只有1分。大約有2,000條記錄,因此手動更改這些記錄很困難。有了這個系統的性質和它的實現,它可以運行1個腳本來協調當前記錄,並有一個單獨的腳本來管理正在進行的條目。

Employee Points Date Previous Note 
Smith, Joe 0.00 3/21/2013 0.25 Rolled Off by System - 30 Day Policy 05/01/2013 
Smith, Joe 0.00 4/1/2013 0.25 Rolled Off by System - 30 Day Policy 06/07/2013 
Smith, Joe 0.00 5/6/2013 0.25 Rolled Off by System - 30 Day Policy 06/07/2013 
Smith, Joe 0.00 5/8/2013 0.50 Rolled Off by System - 30 Day Policy 06/07/2013 
Smith, Joe 0.00 7/10/2013 1.00 Rolled Off by System - 30 Day Policy 08/10/2013 
Jones, Tom 0.00 4/10/2013 1.00 Rolled Off by System - 30 Day Policy 05/22/2013 
Jones, Tom 0.00 4/18/2013 1.00 Rolled Off by System - 60 Day Policy 06/21/2013 
Jones, Tom 0.00 4/22/2013 0.50 Rolled Off by System - 30 Day Policy 07/25/2013 
Jones, Tom 1.50 6/25/2013 2.00 Rolled Off by System - 30 Day Policy 07/25/2013 
Jones, Tom 0.25 7/26/2013  
Jones, Tom 0.25 7/28/2013  

我開始使用的EmployeePerformance表下面,創建一個視圖來顯示每個日記錄之間的數字由他們的ID每個員工。然後,我使用DENSE_RANK()來爲每個員工提供來自考勤視圖的所有信息。我最初的想法是使用增量VARIABLE在每個員工的WHILE循環中循環,然後檢查DATE_DIFFERENCE以查看是否有任何值大於30.如果不是,我計劃將該員工的所有記錄插入到決賽表中,並從Attend2表中刪除它們。更多的腳本比我認爲是必要的。我想到了使用CURSOR,創建一次性通行證,然後再調整一次功能。雖然我沒有使用CURSOR的經驗。

CREATE VIEW Attendance AS 
SELECT A.ID, A.FullName, A.EmployeeID, A.AttendanceDate, A.OccurrenceAmount, A.Comments, A.RecordCreatedDate, A.RecordCreatedUser, (DATEDIFF(DAY, A.AttendanceDate, B.AttendanceDate))*-1 AS DATE_DIFFERENCE 
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY AttendanceDate) AS Row_Num, * 
FROM dbo.EmployeePerformance) AS A 
LEFT JOIN (
SELECT ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY AttendanceDate) AS Row_Num, * 
FROM dbo.EmployeePerformance) AS B 
ON A.EmployeeID=B.EmployeeID AND A.Row_Num=B.Row_Num+1 


SELECT *, DENSE_RANK() OVER (ORDER BY Attendance.EmployeeID) AS Row_Num 
INTO dbo.Attend2 
FROM dbo.Attendance 

我有一些想法,我能想到的解決這個問題,但我希望有人可能有類似的情況或之前這樣一個問題的工作。我更願意將它構建成我可以觸發的一段簡短代碼,並且在低容量環境中使用SQL數據庫時,我並不擔心性能,但我希望找到一個很好的解決方案,以保持性能。心神。感謝您的任何幫助或反饋。

回答

1

我不知道我按照你的方法/期望的結果完全,但對於初學者,你可以使用LEAD代替JOIN/ROW_NUMBER()得到DATEDIFF

SELECT ID 
    , FullName 
    , EmployeeID 
    , AttendanceDate 
    , OccurrenceAmount 
    , Comments 
    , RecordCreatedDate 
    , RecordCreatedUser 
    , DATEDIFF(DAY, AttendanceDate, LEAD(AttendanceDate) OVER(PARTITION BY EmployeeID ORDER BY AttendanceDate))*-1 AS DATE_DIFFERENCE 
FROM dbo.EmployeePerformance) 
+0

謝謝你的提示,我完全忘了LEAD,它會比使用自連接更容易。至於我當然可以理解的結果/方法,並不像我原先想象的那麼容易。淨問題是這樣的... – TSoulDreams

+0

感謝您的提示,我完全忘了LEAD,它會比使用自聯接更容易。至於我當然可以理解的結果/方法,並不像我原先想象的那麼容易。淨問題是這樣的......我有超過1000個記錄,其中有0.25個點到2個點......所以希望的結果是獲取這1000多條記錄,並首先更新並滾出需要的任何點基於規則。然後,根據30,60和90天的業務規則,繼續從該點滾下。 – TSoulDreams