2015-03-11 4 views
4

У меня есть 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; 

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

+0

хороший способ найти трудодня уже было предложено [здесь] (http://stackoverflow.com/questions/252519/count-work-days-between-two-dates) – Sim1

+0

Вычитайте два дня на каждую неделю? – jarlh

ответ

5

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

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 
+1

Использование modulo 7 в 'DATEDIFF (d, 1 - N, @MinDate)% 7 NOT IN (5,6)' является надежным независимо от настроек сервера sql и не зависит от языка. –

+0

благодарит t-clausen.dk, его отпечаток! – user1799596

+0

@Used_By_Already: это не модуль 7, который делает этот запрос независимым от настроек, но неявное преобразование 'int' в' datetime'. Проблема, однако, в том, что это решение имеет ошибку. Если вы попытаетесь изменить '@ MinDate' на' 20140102', вы получите неверные результаты. Возможно, t-clausen.dk означал эту версию DATEDIFF: 'DATEDIFF (DAY, 0, DATEADD (DAY, N - 1, @MinDate))% 7 NOT IN (5,6)'. –

3
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') ; 
+0

Спасибо за ваш ответ Мэтт, но выходные (суббота и воскресенье) не фильтруются. Мне не нужны даты выходных дней в моем коде. – user1799596

+0

Если сравнивать с чек на субботу и воскресенье datepart не является надежным, это зависит от настройки даты, которая по умолчанию может отличаться от базы данных к базе данных. –

+0

Yeh Я думал, что это может быть, плохо удалить вторую версию – Matt

4

Сделайте оригинальный запрос как sub-select, который генерирует все даты между двумя указанными датами затем сделать Filteration в 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') 
+0

безупречно, за исключением того, что мой исследователь SQL не позволит таблице быть таблицей. – CashCow

3

Давным-давно я построил таблицу календаря, чтобы ответить на такие вопросы, как ваша. Главное преимущество, помимо простоты использования, заключается в том, что вы можете посмотреть запрос на таблицу календаря и сказать: «Это , очевидно, справа».

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 Fri 
2014-01-06 Mon 

У меня также есть вид будней, так что я мог бы сомнение его вместо этого.

select cal_date, day_of_week 
from weekdays 
where cal_date between '2014-01-01' and '2014-01-06' 
order by cal_date; 
+0

Как создать таблицу календаря? – user1799596

+0

Вот пример [таблицы календаря с использованием PostgreSQL] (http://stackoverflow.com/a/5030686/562459). Это должно быть довольно легко адаптироваться к SQL Server, тем более, что вам просто нужны два столбца. –

 Смежные вопросы

  • Нет связанных вопросов^_^