我试图找到这样的任何一个月的出席率:
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
这就是我得到的,这很好。
我接下来要做的是省略日期范围(@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 :(得分: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