SQL . SP или функция должны вычислить следующую дату для пятницы

#sql #sql-server-2005 #sql-server-2008

#sql #sql-server-2005 #sql-server-2008

Вопрос:

Мне нужно написать процедуру хранения, которая вернет дату следующей пятницы на заданную дату? например, если дата 05/12/2011, то она должна возвращать дату следующей пятницы как 13.05.2011. Если вы передаете 16.05.2011, то она должна вернуть дату 20.05.2011 (пятница). Если вы передаете пятницу в качестве даты, то она должна возвращать ту же дату.

Ответ №1:

Я бы сделал это скалярным UDF, поскольку его легче использовать для вывода.

 CREATE FUNCTION dbo.GetNextFriday(
@D DATETIME
)
RETURNS DATETIME 
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN DATEADD(DAY,(13 - (@@DATEFIRST   DATEPART(WEEKDAY,@D)))%7,@D)
END
  

Комментарии:

1. Большое спасибо за быстрый ответ.

2. Если @D — суббота (а @@DATEFIRST — 7), функция возвращает предыдущую пятницу, а не следующую пятницу.

Ответ №2:

Это для SQL Server 2008. Для использования в 2005 году просто измените поля даты в соответствии с вашими предпочтениями для преобразования даты и времени в дату. Также предполагается, что вы не изменяете значение начала недели по умолчанию.

 DECLARE @PassedDate date = '5/21/2011';
SELECT DATEADD(DAY,(CASE DATEPART(DW,@PassedDate) WHEN 7 THEN 6 ELSE 6 - DATEPART(DW,@PassedDate) END),@PassedDate);
  

Комментарии:

1. В этом ответе не учитывается параметр @@DATEFIRST.

Ответ №3:

Аналогично ответу выше, но без использования @@DATEFIRST в решении:

 DECLARE @Today DATETIME = GETDATE(); -- any date
DECLARE @WeekdayIndex SMALLINT = DATEPART(WEEKDAY, @Today);
DECLARE @DaysUntilFriday SMALLINT = (13 - @WeekdayIndex) % 7;
DECLARE @UpcomingFridayDate DATETIME = DATEADD(DAY, @DaysUntilFriday, @Today);
SELECT @UpcomingFridayDate ;
  

Ответ №4:

Отличные решения здесь, но я также рекомендую посмотреть таблицы времени: вы можете легко сгенерировать их в Analysis server, и они могут быть очень быстро проиндексированы, что дает вам множество простых способов получить дни следующей недели (среди прочего).

Вы можете узнать больше о них здесь

В нашем случае то же самое решение было бы

 Select MIN(PK_Date) from Time Where PK_Date > @SomeDate AND Day_Of_Week= 6
  

И, конечно, когда вы делаете это для большого набора записей, вы также можете выполнять объединения для максимальной скорости и эффективности.