按月份名称

时间:2016-11-09 08:35:48

标签: sql-server

我试图找到这样的任何一个月的出席率:

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

现在,我如何将这两者结合起来并得到与上面相同的结果?

1 个答案:

答案 0 :(得分: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