2011-12-27 2 views
1

Я хочу рассчитать общее количество Sundays,Mondays...Saturdays между двумя днями. Я хочу сделать это в выбранном запросе, потому что это является обязательным в соответствии с ситуацией, в которой я сейчас работаю.Рассчитать все «По воскресеньям, по понедельникам ... по субботам» между двумя днями в SQL Server

У меня есть рабочий код, где я могу вычислить все воскресные, но не работает в случае понедельников

DECLARE @StartDate DATE = '2011-10-01', 
     @EndDate DATE = '2011-10-31' 

SELECT DayCount = count(*) 
FROM (SELECT TOP (datediff(DAY,@StartDate,@EndDate) + 1) 
         [Date] = dateadd(DAY,ROW_NUMBER() 
        OVER(ORDER BY c1.name), 
        DATEADD(DD,-1,@StartDate)) 
     FROM [master].[dbo].[spt_values] c1) x 
WHERE datepart(dw,[Date]) = 1; 
+1

возможно дубликат [Получить число рабочих дней (по воскресеньям, понедельникам, вторникам) между двумя датами SQL] (http://stackoverflow.com/questions/6684577/get-number-of-weekdays-sundays-mondays -tuesdays-between-two-dates-sql) –

ответ

4

Я думаю, что ваш запрос обеспечивает правильный результат, но может быть немного упрощен.

Это, однако, зависит от SET DATEFIRST настройка.

datepart(dw,[Date]) = 1 будет подсчитывать количество понедельников, если SET DATEFIRST равен 1.

Попробуйте это:

set datefirst 7 -- Sunday 
select datepart(dw, '20111227') 
set datefirst 1 -- Monday 
select datepart(dw, '20111227') 

Результат:

----------- 
3 

----------- 
2 

Update: Другой запрос, который делает то же самое ,

select count(*) as Daycount 
from master..spt_values as Number 
where Number.type = 'P' and 
     dateadd(day, Number.number, @StartDate) <= @EndDate and 
     datepart(dw, dateadd(day, Number.number, @StartDate)) = 1 
+0

Супер Mikael. Работает как шарм. –

2
SELECT dATE , COUNT(dATE) FROM (
       SELECT TOP (datediff(DAY,@StartDate,@EndDate) + 1) [Date] = DATENAME(dw , dateadd(DAY,ROW_NUMBER() OVER(ORDER BY c1.name), 
          DATEADD(DD,-1,@StartDate)))   
          FROM [master].[dbo].[spt_values] c1) X 
          GROUP BY Date 
+0

Ваше решение также работает, но я поеду с Микаэлем Эрикссоном, потому что мне нужны колонки с мудрыми ответами. В любом случае, если бы у меня была возможность отметить, что оба ответа верны, я бы сделал это сегодня. Благодарю. –

0

Расчет простого количества отдельных дней между двумя датами НЕ должен содержать таблицу чисел. Форсирование ввода-вывода в простой расчет даты не является хорошей практикой.

Вы можете сделать простой расчет, указав количество недель между двумя датами и отрегулировав, где нужный день падает относительно конечных периодов.

Но я хочу представить другой способ сделать это, что на самом деле позволяет указать любой шаблон дней, который вы хотите подсчитать. Например, так же легко рассчитать количество суббот и воскресенья одновременно, так как оно рассчитает количество понедельников. Я также постарался сделать этот запрос полностью независимым от настройки SET DATEFIRST.

DECLARE 
    @StartDate date = '2011-10-01', 
    @EndDate date = '2011-10-31'; 

WITH A AS (SELECT DayCount = DateDiff(day, @StartDate, @EndDate) + 1), 
B AS (
    SELECT 
     DayCount, 
     WeekCount = DayCount + 6/7, 
     Dow = DateDiff(day, '18991230', @StartDate) % 7 FROM A 
) 
SELECT 
    MondayCount = 
     Len(Replace(Substring(
     Replicate('0100000', WeekCount), 
     Dow, DayCount 
    ), '0', '')) 
FROM B; 

Трюк - это строка внутри функции Replicate. Он кодирует понедельник, помещая 1 во вторую позицию (начиная с воскресенья в первый день).

Вы можете почувствовать себя отталкиваемым таким способом, как это, - но я играл с этим раньше и ожидаю, что вам будет очень сложно улучшить его скорость с помощью математики с обычной математикой (в частности, способный вычислять в течение нескольких дней одновременно).

0
select 
SUM(CASE WHEN datepart(dw, dateadd(day, Number.number, @fromDate)) = 1 THEN 1 ELSE 0 END) Sunday, 
SUM(CASE WHEN datepart(dw, dateadd(day, Number.number, @fromDate)) = 2 THEN 1 ELSE 0 END) Monday, 
SUM(CASE WHEN datepart(dw, dateadd(day, Number.number, @fromDate)) = 3 THEN 1 ELSE 0 END) Tuesday, 
SUM(CASE WHEN datepart(dw, dateadd(day, Number.number, @fromDate)) = 4 THEN 1 ELSE 0 END) Wednesday, 
SUM(CASE WHEN datepart(dw, dateadd(day, Number.number, @fromDate)) = 5 THEN 1 ELSE 0 END) Thursday, 
SUM(CASE WHEN datepart(dw, dateadd(day, Number.number, @fromDate)) = 6 THEN 1 ELSE 0 END) Friday, 
SUM(CASE WHEN datepart(dw, dateadd(day, Number.number, @fromDate)) = 7 THEN 1 ELSE 0 END) Saturday 
from master..spt_values as Number 
where Number.type = 'P' and dateadd(day, Number.number, @fromDate) <= @toDate 
Смежные вопросы