2016-11-09 37 views
0

獲取考勤我試圖找到考勤像這樣某個月:按月名

DECLARE @StartDate DATE 
DECLARE @EndDate DATE 
SET @StartDate = '2016/10/01' 
SET @EndDate = '2016/10/31' 


SELECT 
StaffAttendance.StaffId, DATENAME(MONTH, @StartDate) AS [ForMonth], 
    (DATEDIFF(dd, @StartDate, @EndDate) + 1) 
    -(DATEDIFF(wk, @StartDate, @EndDate) * 1) 
    -(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END) AS TotalWorkingDays, 
    SUM(StaffAttendance.AttendanceStatusId) AS TotalDaysWorked FROM StaffAttendance WHERE [Date] BETWEEN @StartDate AND @EndDate AND StaffAttendance.AttendanceStatusId = 1 GROUP BY StaffAttendance.StaffId 

而這就是我得到,這只是罰款。

enter image description here

我想接下來做的就是忽略日期範圍(@StartDate DATE,@EndDate DATE)和使用月份名稱,而不是像 - 「月」,而不是像'10月號「。因此,該用戶會給出月份名稱,並自動計算該月份的開始日期和結束日期。我得到了Felix Pamittan的幫助。

DECLARE @month VARCHAR(9) = 'february'; 

WITH CteMonths(n, m) AS(
    SELECT 1, 'January' UNION ALL 
    SELECT 2, 'February' UNION ALL 
    SELECT 3, 'March' UNION ALL 
    SELECT 4, 'April' UNION ALL 
    SELECT 5, 'May' UNION ALL 
    SELECT 6, 'June' UNION ALL 
    SELECT 7, 'July' UNION ALL 
    SELECT 8, 'August' UNION ALL 
    SELECT 9, 'September' UNION ALL 
    SELECT 10, 'October' UNION ALL 
    SELECT 11, 'November' UNION ALL 
    SELECT 12, 'December' 
) 
SELECT 
    DATEADD(MONTH, n - 1, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)) AS StartDate, 
    DATEADD(DAY, -1, DATEADD(MONTH, n, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0))) AS EndDate 
FROM CteMonths 
WHERE m = @month 

現在,我該如何結合這兩個並得到與上述相同的結果?

回答

0

使用CROSS APPLY

DECLARE @month VARCHAR(9) = 'february'; 

WITH CteMonths(n, m) AS(
    SELECT 1, 'January' UNION ALL 
    SELECT 2, 'February' UNION ALL 
    SELECT 3, 'March' UNION ALL 
    SELECT 4, 'April' UNION ALL 
    SELECT 5, 'May' UNION ALL 
    SELECT 6, 'June' UNION ALL 
    SELECT 7, 'July' UNION ALL 
    SELECT 8, 'August' UNION ALL 
    SELECT 9, 'September' UNION ALL 
    SELECT 10, 'October' UNION ALL 
    SELECT 11, 'November' UNION ALL 
    SELECT 12, 'December' 
) 
SELECT 
    sa.StaffId, 
    DATENAME(MONTH, t.StartDate) AS [ForMonth], 
    (DATEDIFF(dd, t.StartDate, t.EndDate) + 1) 
     - (DATEDIFF(wk, t.StartDate, t.EndDate) * 1) 
     - (CASE WHEN DATENAME(dw, t.StartDate) = 'Sunday' THEN 1 ELSE 0 END) AS TotalWorkingDays, 
    SUM(sa.AttendanceStatusId) AS TotalDaysWorked 
FROM StaffAttendance sa 
CROSS APPLY(
    SELECT 
     DATEADD(MONTH, n - 1, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0)) AS StartDate, 
     DATEADD(DAY, -1, DATEADD(MONTH, n, DATEADD(YEAR, DATEDIFF(YEAR, 0, GETDATE()), 0))) AS EndDate 
    FROM CteMonths 
) t 
WHERE 
    sa.[Date] >= t.StartDate 
    AND sa.[Date] < DATEADD(DAY, 1, t.EndDate) 
    AND sa.AttendanceStatusId = 1 
GROUP BY sa.StaffId