Перечислите все рабочие даты между двумя датами в SQL
У меня есть код SQL для создания списка дат между двумя датами, но я хочу сгенерировать дни недели (рабочие дни) из данных двух дат,
DECLARE @MinDate DATE = '20140101', @MaxDate DATE = '20140106'; SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1) Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1,@MinDate) FROM sys.all_objects a CROSS JOIN sys.all_objects b;
Это мой код, поэтому, пожалуйста, предложите мне получить список будних дней в одиночку. В онлайн-источниках есть код, чтобы найти количество дней, не включенных в список всех дат, и есть моя путаница.
- Разрешить удаленное подключение только для определенных пользователей
- Есть ли способ генерировать миллионные адреса mac более эффективно?
- Экземпляр по умолчанию для SQL Server 2012 не работает
- как вставить значение в таблицу типов данных изображения
- Настройка состояния NOCOUNT с локальной переменной
- Как просмотреть запрос, который использовался для создания таблицы?
- Ошибка «Недопустимое имя столбца» при вызове вставки после создания таблицы
- «Сервисный брокер». Главный сервер «sa» не может получить доступ к базе данных в контексте текущей безопасности
- Последовательность SQL Server 2012
- Недостаток узла главной таблицы, SQL Server 2012 SP1
- Получить файл .sql из базы данных SQL Server 2012
- Как предотвратить «истечение тайм-аута запроса»? (Ошибка SQLNCLI11 '80040e31')
- Создать отфильтрованный индекс, не работающий в SQL Server 2012 Express
Попробуй это:
DECLARE @MinDate DATE = '20140101', @MaxDate DATE = '20140106' ;WITH N1 (N) AS (SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (N)), N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2), N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2), N4 (N) AS (SELECT ROW_NUMBER() OVER(ORDER BY N1.N) FROM N3 AS N1 CROSS JOIN N3 AS N2) SELECT Date = DATEADD(DAY, N - 1, @MinDate) FROM N4 WHERE N < DATEDIFF(DAY, @MinDate, @MaxDate) + 2 AND DATEDIFF(DAY, 1 - N, @MinDate) % 7 NOT IN (5,6)
Результат:
Date 2014-01-01 2014-01-02 2014-01-03 2014-01-06
Сделайте исходный запрос в качестве sub-select
который генерирует все даты между двумя заданными датами, а затем выполняет фильтрацию во outer query
.
SET DATEFIRST 1 select [Date] from ( SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1) Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1,@MinDate) FROM sys.all_objects a CROSS JOIN sys.all_objects b ) where datename(dw,[Date]) not in ('Saturday','Sunday')
Давным-давно я построил таблицу календаря, чтобы ответить на такие вопросы, как ваша. Главное преимущество, помимо простоты использования, заключается в том, что вы можете посмотреть запрос на таблицу календаря и сказать: «Это, очевидно, правильно».
select cal_date, day_of_week from calendar where day_of_week in ('Mon', 'Tue', 'Wed', 'Thu', 'Fri') and cal_date between '2014-01-01' and '2014-01-06' order by cal_date;
cal_date day_of_week - 2014-01-01 Wed 2014-01-02 Thu 2014-01-03 Пт 2014-01-06 Пн
У меня также есть вид на будние дни, поэтому я мог бы запросить его.
select cal_date, day_of_week from weekdays where cal_date between '2014-01-01' and '2014-01-06' order by cal_date;
DECLARE @MinDate DATE = '20140101', @MaxDate DATE = '20140106'; SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1) Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1,@MinDate) FROM sys.all_objects a CROSS JOIN sys.all_objects b WHERE datename(dw,@MinDate) NOT IN ('Saturday','Sunday') AND datename(dw,@MaxDate) NOT IN ('Saturday','Sunday') ;