Как вычислить рабочие дни в Mssql?
У меня возникла трудность с MSSQL. Вообщем, у меня есть два поля, которым соответствуют две даты. Мне надо узнать разницу в днях между этими датыми, но при этом, чтобы в счет не принимались выходные. Знаю, что разницу можно вычислить с помощью функции DATEDIFF(). Подскажите, можно ли написать фенкцию, которая бы учитывала и выходные дни?
CREATE PROCEDURE dbo.day_notholiday
@dat_n datetime,
@dat_f datetime
AS
declare @count int
declare @dat_dif datetime
set @count=0
set @dat_dif=@dat_n
while @dat_dif<=@dat_f
begin
set @count=@count+1
if DATEPart(weekday, @dat_dif)= 1 or DATEPart(weekday, @dat_dif)= 7
set @count=@count-1
set @dat_dif=DateAdd(day,1,@dat_dif)
end
select @count as Колво
GO
может конечно кто-то решит это и меньшими ресурсами , но на быструю руку ...
Удачи!
Возможно эта проца даст тебе ответ:
CREATE PROCEDURE dbo.day_notholiday
@dat_n datetime,
@dat_f datetime
AS
declare @count int
declare @dat_dif datetime
set @count=0
set @dat_dif=@dat_n
while @dat_dif<=@dat_f
begin
set @count=@count+1
if DATEPart(weekday, @dat_dif)= 1 or DATEPart(weekday, @dat_dif)= 7
set @count=@count-1
set @dat_dif=DateAdd(day,1,@dat_dif)
end
select @count as Колво
GO
может конечно кто-то решит это и меньшими ресурсами , но на быструю руку ...
Удачи!
Большое спасибо dragonv!
У меня похожие мысли были, но не мог это воплотить в код. В принципе тут все мне понятно, крое одного - как мне применить эту процедуру в ходе выборки?
Большое спасибо dragonv!
У меня похожие мысли были, но не мог это воплотить в код. В принципе тут все мне понятно, крое одного - как мне применить эту процедуру в ходе выборки?
Преобразуй это в функцию
CREATE FUNCTION dbo.day_notholiday_1 (@dat_n datetime, @dat_f datetime)
RETURNS int
AS
BEGIN
declare @count int
declare @dat_dif datetime
set @count=0
set @dat_dif=@dat_n
while @dat_dif<=@dat_f
begin
set @count=@count+1
if DATEPart(weekday, @dat_dif)= 1 or DATEPart(weekday, @dat_dif)= 7
set @count=@count-1
set @dat_dif=DateAdd(day,1,@dat_dif)
end
return @count
END
А вот так реализация
select dbo.day_notholiday_1('2005-06-01', '2005-06-15')
Удачи!
Преобразуй это в функцию
CREATE FUNCTION dbo.day_notholiday_1 (@dat_n datetime, @dat_f datetime)
RETURNS int
AS
BEGIN
declare @count int
declare @dat_dif datetime
set @count=0
set @dat_dif=@dat_n
while @dat_dif<=@dat_f
begin
set @count=@count+1
if DATEPart(weekday, @dat_dif)= 1 or DATEPart(weekday, @dat_dif)= 7
set @count=@count-1
set @dat_dif=DateAdd(day,1,@dat_dif)
end
return @count
END
А вот так реализация
select dbo.day_notholiday_1('2005-06-01', '2005-06-15')
Удачи!
Классно! Большое спасибо dragonv :)
Все получилось, только есть несколько вопросов.
У меня в таблице есть такие столбцы, как номер груза, дата его отправки и дата доставки. Мне надо вывести данные, включая разницу в рабочих днях и разницу в календарных днях. Я делаю такой запрос:
select
waybill_num as 'Номер накладной,
convert(char, date_of_depart, 102) as 'Дата отправки',
convert(char, date_of_rec, 102) as 'Дата получения',
DATEDIFF(dd, date_of_depart, date_of_rec) as 'Срок доставки в календарных днях',
dbo.day_notholiday_1(date_of_depart, date_of_rec) as 'Срок доставки в рабочих днях'
from way_bills
У меня все выводит но разница с учетом выходных выводилась не всегда корректно. Получалось, что разница в календарных днях была, скажем, 3 дня, а с учетом выходных 4 дня, то есть на день больше. Функция считала включительно и день отправки и день получения. Тогда я подправил функцию. Вот она:
CREATE FUNCTION dbo.day_notholiday_1 (@dat_n DATETIME, @dat_f DATETIME)
RETURNS INT
AS
BEGIN
DECLARE @count INT
DECLARE @dat_dif DATETIME
SET @count=DATEDIFF(dd, @dat_n, @dat_f)
SET @dat_dif=@dat_n
WHILE @dat_dif<=@dat_f
BEGIN
IF DATEPART(WEEKDAY, @dat_dif)= 1 OR DATEPART(WEEKDAY, @dat_dif)= 7
SET @count=@count-1
SET @dat_dif=DATEADD(day, 1, @dat_dif)
END
RETURN @count
END
Теперь ситуация стала другой. Теперь, если отправка происходила в пятницу, а получение в понедельник срок доставки с учетом выходных равнялся 0 :(
Хочется усовершенствовать функцию. Тут кстати возник еще один вопрос. Надо учитывать и праздничные дни, а также случаи, когда суббота рабочий день. Для этого я создал отдельную таблицу с данными о всех нерабочих днях в году.
Подскажи пожалуйста, как теперь реализовать эту же функцию, но с учетом того, чтобы срок доставки груза вычислялся с учетом данных таблицы с нерабочими днями?
select
waybill_num as 'Номер накладной,
convert(char, date_of_depart, 102) as 'Дата отправки',
convert(char, date_of_rec, 102) as 'Дата получения',
DATEDIFF(dd, date_of_depart, date_of_rec)+1 as 'Срок доставки в календарных днях',
dbo.day_notholiday_1(date_of_depart, date_of_rec) as 'Срок доставки в рабочих днях'
from way_bills
Функцию не нужно было править,т.к. она тоже правильно показывала разницу, а если тебе нужно еще и прибавить таблицу праздников , то
вот пример реализации :
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Holiday]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[Holiday]
GO
CREATE TABLE [dbo].[Holiday] (
[Id_tabl] [int] IDENTITY (1, 1) NOT NULL ,
[Holday] [datetime] NULL
) ON [PRIMARY]
GO
CREATE FUNCTION dbo.day_notholiday_1 (@dat_n datetime, @dat_f datetime)
RETURNS int
AS
BEGIN
declare @count int
declare @dat_dif datetime
set @count=0
set @dat_dif=@dat_n
while @dat_dif<=@dat_f
begin
set @count=@count+1
if DATEPart(weekday, @dat_dif)= 1 or DATEPart(weekday, @dat_dif)= 7 or Exists(select Holday from Holiday where Holday=@dat_dif)
/* или только Exists(select Holday from Holiday where Holday=@dat_dif) если в таблице у тебя внесены все нерабочие дни: праздничные+выходные*/
set @count=@count-1
set @dat_dif=DateAdd(day,1,@dat_dif)
end
return @count
END
Если что,пиши на мыло [email]vitek777@yandex.ru[/email]
Удачи!!!
Все просто супер заработало :) Ты меня очень сильно выручил :)
Еще раз спасибо.