2016-11-09 35 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