Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как вычислить рабочие дни в Mssql?

1.9K
26 мая 2005 года
kasap
168 / / 07.04.2005
Привет всем.

У меня возникла трудность с MSSQL. Вообщем, у меня есть два поля, которым соответствуют две даты. Мне надо узнать разницу в днях между этими датыми, но при этом, чтобы в счет не принимались выходные. Знаю, что разницу можно вычислить с помощью функции DATEDIFF(). Подскажите, можно ли написать фенкцию, которая бы учитывала и выходные дни?
12K
31 мая 2005 года
dragonv
3 / / 31.05.2005
Возможно эта проца даст тебе ответ:

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

может конечно кто-то решит это и меньшими ресурсами , но на быструю руку ...
Удачи!
1.9K
31 мая 2005 года
kasap
168 / / 07.04.2005
Цитата:
Originally posted by dragonv
Возможно эта проца даст тебе ответ:

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!

У меня похожие мысли были, но не мог это воплотить в код. В принципе тут все мне понятно, крое одного - как мне применить эту процедуру в ходе выборки?

12K
01 июня 2005 года
dragonv
3 / / 31.05.2005
Цитата:
Originally posted by kasap
Большое спасибо 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')
Удачи!

1.9K
01 июня 2005 года
kasap
168 / / 07.04.2005
Цитата:
Originally posted by 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')
Удачи!



Классно! Большое спасибо 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 :(
Хочется усовершенствовать функцию. Тут кстати возник еще один вопрос. Надо учитывать и праздничные дни, а также случаи, когда суббота рабочий день. Для этого я создал отдельную таблицу с данными о всех нерабочих днях в году.
Подскажи пожалуйста, как теперь реализовать эту же функцию, но с учетом того, чтобы срок доставки груза вычислялся с учетом данных таблицы с нерабочими днями?

12K
02 июня 2005 года
dragonv
3 / / 31.05.2005
Вот так будет правильно показывать все дни. Функция Datediff в данном случае не совсем подходит,так как считает разницу, но не включительно (будь осторожнее с этой функцией!!!).

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]

Удачи!!!
1.9K
06 июня 2005 года
kasap
168 / / 07.04.2005
Спасибо тебе dragonv.

Все просто супер заработало :) Ты меня очень сильно выручил :)

Еще раз спасибо.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог