Рассчитать все «воскресенья, понедельники ... субботы» между двумя днями в SQL Server - PullRequest
1 голос
/ 27 декабря 2011

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

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

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;

Ответы [ 4 ]

4 голосов
/ 27 декабря 2011

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

Однако он зависит от настройки 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

Обновление: Другой запросчто делает то же самое.

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
2 голосов
/ 27 декабря 2011
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 голосов
/ 10 декабря 2015
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
0 голосов
/ 20 декабря 2012

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

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

Но я хочу представить другой способ сделать это, который на самом деле позволяет вам указать любой график дней, который вы хотите считать.Например, рассчитать количество суббот и воскресений одновременно так же просто, как и количество понедельников.Я также старался сделать этот запрос полностью независимым от настройки 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 во вторую позицию (начиная с воскресенья в качестве первого дня).

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

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