Я хочу добавить фильтр к запросу, который захватывает даты до последних 5 РАБОЧИХ ДНЕЙ.
declare @DataRetentionPeriod INT =5
Delete FROM dbo.table1 pt
WHERE CONVERT(varchar,pt.ptStampDateTime, 112) < CONVERT( VARCHAR, DATEADD(DAY, @DataRetentionPeriod * -1, GETDATE()), 112)
Итак, я хочу удалить данные из таблицы 1, но хочу сохранить данные в этой таблице до последних 5 рабочих дней, т. е. если сценарий запускается в понедельник, он не должен учитывать субботу и воскресенье в фильтре и должен удалять записи до прошлой пятницы - последних недель. данные не должны удаляться. А если на прошлой неделе был какой-либо праздничный день, необходимо добавить перемещение еще на один день назад, чтобы сохранить данные за 5 рабочих дней.
У меня есть функция, которая дает мне последний рабочий день указанной @date -
select dbo.fn_previous_working_day(@date)
Если дата сегодня - выдаст вчерашний день Если дата понедельник, то будет пятница, а если пятница была выходным днем, то будет четверг.
У меня есть еще одна функция, которая выдает NULL, если указанная дата является рабочей датой, и дает подробную информацию о дате, если это праздник/выходной день.
select dbo.fn_working_day(@date)
Но я просто не могу найти способ добавить фильтр, чтобы просто подсчитывать последние 5 рабочих дней (или любое другое число, указанное в переменной @dataretentionPeriod).
Я даже попробовал это, чтобы получить последние 5 рабочих дат.
declare @i int =0,
@date datetime,
@newdate datetime,
@daten datetime = '2024-04-04',
@datet datetime
while @i <5
Begin
select @date = convert(datetime,convert(varchar, dbo.fn_previous_working_day(@daten-@i),112))
select @datet = convert(datetime,convert(varchar, dbo.fn_previous_working_day(@date),112))
select @newdate = @datet
set @i = @i+1
end
select @newdate
Но это дает мне 27-04-2024 вместо 26-04-2024, так как на этой неделе два государственных праздника, и счетчик прыгает только на 1 день, а не на 1 рабочий день - как я могу заставить счетчик прыгать на 1 рабочий день вместо 1 дня
Я ожидаю, что фильтр даты будет учитывать только 5 рабочих дней вместо 5 дней.
Примечание: преобразование дат в/из текста для сравнения или других операций — плохая практика, которой следует избегать. Если значением является дата или дата/время, сохраните его как соответствующий тип и ограничьте операции собственными операторами и функциями даты/времени. Условие WHERE
в первом блоке кода лучше записать как WHERE pt.ptStampDateTime < DATEADD(DAY, @DataRetentionPeriod * -1, CONVERT(DATE, GETDATE()))
. Преобразования текста в исходном состоянии не Саргабельны, то есть индексы использовать нельзя.
Дейл К. Я добавлял sqlDeveloper, и тег показывал oracle-sqldeveloper, поэтому я добавил его, полагая, что он предназначен как для разработчика Oracle, так и для sql.
Если вы серьезно все еще используете 2008 R2, вам необходимо срочно изучить возможность обновления.
Если вы можете предположить (это нормально для большинства стран), что самый длинный календарный период, который следует учитывать, составляет 10 дней, из которых мы всегда можем найти 5 рабочих дней (если нет, вы можете скорректировать):
with Seq as (
select Offset
from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) T (Offset)
), Last10Days as (
select dateadd(day,-Offset, getdate()) as Dte
from Seq
)
select top 5 *
from Last10Days L10D
where dbo.fn_working_day(Dte) is null
-- I simulated with this (I don't have your function)
-- exists (select 1 as IsWeekDay where datename(weekday, L10D.Dte) not in ('Saturday', 'Sunday'))
order by Dte desc
Мы создаем календарь за последние 10 дней и тестируем все с помощью вашей функции, сохраняя рабочие дни, а затем берем самые последние 5.
10 дней не всегда достаточно; В оперативном штабе сказано, что два государственных праздника составляют одну неделю. Это означает, что у вас может быть две субботы, два воскресенья и два государственных праздника, и останется только 4 рабочих дня, хотя на самом деле вам нужно 5.
Спасибо @matbailie, мы можем просто добавить ,(11),(12),(13),(15) после (10), чтобы увеличить окно до 15 дней. Или больше
Таблица-календарь стоила бы затраченных усилий. Кстати, LOOPS следует избегать любой ценой.