Tôi luôn đề xuất Bảng lịch , thì bạn có thể chỉ cần sử dụng:
SELECT COUNT(*)
FROM dbo.CalendarTable
WHERE IsWorkingDay = 1
AND [Date] > @StartDate
AND [Date] <= @EndDate;
Vì SQL không có kiến thức về các ngày lễ, chẳng hạn như số ngày trong tuần giữa hai ngày không phải lúc nào cũng đại diện cho số ngày làm việc. Đây là lý do tại sao một bảng lịch là bắt buộc đối với hầu hết các cơ sở dữ liệu. Chúng không tốn nhiều bộ nhớ và đơn giản hóa rất nhiều truy vấn.
Nhưng nếu đây không phải là một tùy chọn thì bạn có thể tạo một bảng ngày tháng tương đối dễ dàng và sử dụng nó
SET DATEFIRST 1;
DECLARE @StartDate DATETIME = '20131103',
@EndDate DATETIME = '20131104';
-- GENERATE A LIST OF ALL DATES BETWEEN THE START DATE AND THE END DATE
WITH AllDates AS
( SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate))
D = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.Object_ID), @StartDate)
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
)
SELECT WeekDays = COUNT(*)
FROM AllDates
WHERE DATEPART(WEEKDAY, D) NOT IN (6, 7);
CHỈNH SỬA
Nếu bạn cần tính toán sự khác biệt giữa hai cột ngày, bạn vẫn có thể sử dụng bảng lịch của mình như vậy:
SELECT t.ID,
t.Date1,
t.Date2,
WorkingDays = COUNT(c.DateKey)
FROM TestTable t
LEFT JOIN dbo.Calendar c
ON c.DateKey >= t.Date1
AND c.DateKey < t.Date2
AND c.IsWorkingDay = 1
GROUP BY t.ID, t.Date1, t.Date2;