Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Функция для расчета количества будних дней  [new]
vani
Member

Откуда: Санкт-Петербург
Сообщений: 66
Есть на входе @dt1 и @dt2. Страна - Россия.

Кто поделится?
21 июн 04, 18:07    [755362]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
vani
Member

Откуда: Санкт-Петербург
Сообщений: 66
Просто надо грамотно выкинуть datepart 6 и 7
21 июн 04, 18:08    [755369]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
EvAlex
Member

Откуда: Israel
Сообщений: 1001
CREATE FUNCTION UDF_T_MASHOV_GET_DIFF (@srcDt datetime,@today datetime)
RETURNS smallint AS  
BEGIN 
declare @tempDt datetime
DECLARE @weekend INTEGER,@result INTEGER,@holiday INTEGER
set @today=@today
SELECT @weekend=0,@result=0,@holiday=0
select @holiday=count(*) from T_MASHOV_DOM_HOLIDAY WITH(NOLOCK) where (times between @srcDt and @today) and datepart(weekday,times)<6
Set @tempDt=@srcDt
while @tempDt<@today
BEGIN
	Set @tempDt=dateadd(day,1,@tempDt)
	If datepart(weekday,@tempDt)>5 AND @tempDt<@today Set @weekend=@weekend+1
END
Set @result=datediff(day,@srcDt,@today)-@weekend-@holiday
return @result
END

Допольнительно к будням - я держу табличку T_MASHOV_DOM_HOLIDAY (times DATETIME, descr VARCHAR(255) с празниками, которую клиент сам заполняет.
А вот на Россию - сам переделаешь.
21 июн 04, 18:16    [755393]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
vani
Member

Откуда: Санкт-Петербург
Сообщений: 66
Ок. Спасибо. Праздники мне в принципе не нжны совсемю
Кстати, нашел ещё функцию. :)

[url=http://]https://www.sql.ru/subscribe/071.shtml[/url]
21 июн 04, 18:26    [755426]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
EvAlex
Member

Откуда: Israel
Сообщений: 1001
Ага, мне клиент тоже про рпазники ничего вначале не говорил...
Та фунция лучше, сама идея лучше, но она тоже для России нуждается в переделке...
(и мучает меня вопрос, что является первой неделей года - неделя с первого января или продолжается в последней уходящего( т.е в этом году второе января это 1 неделя 2005 или 36-я 2004?)
21 июн 04, 18:40    [755481]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
_bob
Member

Откуда: Москва
Сообщений: 1654
to EvAlex:
как известно, в неделе всегда 7 дней, причём два из них - выходные
поэтому берём на вооружение здравый смысл и логику и получаем:

CREATE FUNCTION dbo.weekend_away (@from datetime, @to datetime)
RETURNS int AS
BEGIN
declare @weeks int, @days int, @days_all int
if isdate(@from) = 0 or isdate(@to) = 0 or @from>=@to
begin
return 0
end
else
begin
select @days_all = datediff(dd, @from, @to), @weeks = datediff(wk, @from, @to)
if @weeks = 0
return @days_all
else
return datepart(dw, @to) - datepart(dw, @from)+(@weeks)*5
end
return 0
END

если не лень занести праздники в табличку, то нужно ещё сосчитать сколько праздников попадает в интервал и вычесть
21 июн 04, 18:41    [755484]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
EvAlex
Member

Откуда: Israel
Сообщений: 1001
2: _bob
тогда
select  dbo.weekend_away2('20040501','20040502')
----------- 

-1 (1 row(s) affected)
21 июн 04, 19:16    [755575]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
EvAlex
Member

Откуда: Israel
Сообщений: 1001
Что-то не вижу здравого смылсла
и вообще так красивее (твоё же)...
CREATE FUNCTION dbo.weekend_away (@from datetime, @to datetime) 
	RETURNS int AS 
BEGIN 
	IF  @from>=@to  
		RETURN 0
	IF DateDiff(Week, @from, @to) = 0
		RETURN DateDiff(Day, @from, @to)
		
	RETURN DatePart(WeekDay, @to) - DatePart(WeekDay, @from) + DateDiff(Week, @from, @to)*5
END
21 июн 04, 19:22    [755585]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
_bob
Member

Откуда: Москва
Сообщений: 1654
понятно, что красивее, но я уже выдвигался домой и решил, что идею донести важнее, чем вылизать код
но согласись, что если вызывать функцию много раз, перебор всех дат займет много времени
22 июн 04, 11:58    [756645]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
А не проще сделать служебную табличку, в которую залить нужные даты хоть на 40 лет вперед? а потом дергать из неё? Уж тормозов то точно не должно быть. А залить - разовая работа...
22 июн 04, 12:06    [756681]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
_bob
Member

Откуда: Москва
Сообщений: 1654
to tpg:

задача: пусть у Вас в базе 100 000 невыполненных поручений, каждый вид поручения должен быть выполнен за определенное количество дней, нужно проехаться по ним, найти те, которые просрочены более чем на три дня и снять с з/п исполнителя 1$ за каждую такую задержку.

а теперь хотелось бы понять, как в этом ключе (функция требуется для чего-то подобного) использовать таблицу с забитыми в неё данными на 40 лет вперед
22 июн 04, 12:22    [756755]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Задача была про
автор
Функция для расчета количества будних дней
22 июн 04, 12:24    [756771]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
vani
Member

Откуда: Санкт-Петербург
Сообщений: 66
To EvAlex

Взял твою функцию

Пофикси у себя:

select @holiday=count(*) from T_MASHOV_DOM_HOLIDAY WITH(NOLOCK) where (times between @srcDt and @today) and datepart(weekday,times)<6

на

select @holiday=count(*) from T_MASHOV_DOM_HOLIDAY WITH(NOLOCK) where times >= @srcDt and times < @today and datepart(weekday,times)<6

Тогда все чики-пуки. :)

Спасибо всем остальным, но вы тестировали свои функции хоть чуток?

DECLARE @dt1 datetime 
DECLARE @dt2 datetime
DECLARE @i int
SET @dt1 = '20040101'
SET @dt2 = '20031201'
SET @i = 0

WHILE @i < 50 BEGIN
	PRINT  CONVERT(varchar(10),@dt1,112)+ '-' +CONVERT(varchar(10),@dt2,112) + ' ' + CAST(dbo.uf_getworkdays(@dt1, @dt2) as varchar(3))
	SET @dt2 = @dt2 + 1
	SET @i = @i + 1
END


Попробуйте :) Занимательно. :)
22 июн 04, 19:23    [758623]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
vani
Member

Откуда: Санкт-Петербург
Сообщений: 66
А на перенос праздников, если те выпадают на выходные я просто забил, так как мне это ни к чему. Хотя алгоритм прост. Кому надо - доделайте и постите. :)

CREATE FUNCTION dbo.uf_getworkdays (@srcDt datetime,@today datetime)
RETURNS smallint 
AS
BEGIN

DECLARE @tempDt datetime
DECLARE @weekend int
DECLARE @result int
DECLARE @holiday int

SET @weekend = 0
SET @result = 0
SET @holiday = 0

DECLARE @tmp TABLE (dt datetime)

INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0101'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0102'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0107'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0223'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0308'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0501'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0502'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0509'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '0612'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '1107'
INSERT INTO @tmp SELECT CAST(YEAR(@srcDt) as varchar(4)) + '1212'

SELECT @holiday = COUNT(*) FROM @tmp WHERE dt >= @srcDt and dt < @today and DATEPART(weekday, dt) < 6

SET @tempDt = @srcDt

WHILE @tempDt < @today BEGIN
	SET @tempDt=DATEADD(day, 1, @tempDt)
	IF DATEPART(weekday, @tempDt) > 5 and @tempDt<@today SET @weekend = @weekend + 1
END

SET @result = DATEDIFF(day, @srcDt, @today) - @weekend - @holiday

RETURN @result

END
22 июн 04, 19:27    [758627]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
vani
Member

Откуда: Санкт-Петербург
Сообщений: 66
+ ещё к этому интервал между годами. Там праздники н ебудут считаться. :)
22 июн 04, 19:28    [758631]     Ответить | Цитировать Сообщить модератору
 Re: Функция для расчета количества будних дней  [new]
LSV
Member [заблокирован]

Откуда: Киев
Сообщений: 30817
полностью согласен с tpg :
очень полезно сделать служебную табличку:
Дата- №недели- ДеньНедели- НомерМесяца-НомерКвартала- ПрочиеПризнаки(праздник, банковский день, первый день месяца и т.п.)

Хотя эти цифры легко и так получить, но делать в запросе вычисление
нужного параметра это прямой путь к неиспользованию индекса по дате.
С такой таблицей очень удобно делать сложные и быстрые запросы с датами и периодами.
23 июн 04, 11:19    [759521]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить