Посчитайте только рабочие дни (исключая выходные и праздничные дни) и добавьте фильтр, соответствующий запросу

Я хочу добавить фильтр к запросу, который захватывает даты до последних 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 дней.

Таблица-календарь стоила бы затраченных усилий. Кстати, LOOPS следует избегать любой ценой.

John Cappelletti 21.08.2024 01:54

Примечание: преобразование дат в/из текста для сравнения или других операций — плохая практика, которой следует избегать. Если значением является дата или дата/время, сохраните его как соответствующий тип и ограничьте операции собственными операторами и функциями даты/времени. Условие WHERE в первом блоке кода лучше записать как WHERE pt.ptStampDateTime < DATEADD(DAY, @DataRetentionPeriod * -1, CONVERT(DATE, GETDATE())). Преобразования текста в исходном состоянии не Саргабельны, то есть индексы использовать нельзя.

T N 21.08.2024 02:42

Дейл К. Я добавлял sqlDeveloper, и тег показывал oracle-sqldeveloper, поэтому я добавил его, полагая, что он предназначен как для разработчика Oracle, так и для sql.

user25935915 21.08.2024 05:25

Если вы серьезно все еще используете 2008 R2, вам необходимо срочно изучить возможность обновления.

Dale K 21.08.2024 06:52
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
4
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы можете предположить (это нормально для большинства стран), что самый длинный календарный период, который следует учитывать, составляет 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 21.08.2024 09:00

Спасибо @matbailie, мы можем просто добавить ,(11),(12),(13),(15) после (10), чтобы увеличить окно до 15 дней. Или больше

tinazmu 21.08.2024 09:18

Другие вопросы по теме