Добавить Конкретный день, год, месяц, неделю в конкретную дату с использованием сервера sql

Я застрял в одном запросе. Нужна ваша помощь.

У меня есть таблица tblEventCalendarEvents

id    name      start_date   end_date    rec_type
891 Bob Lehman  2012-05-01   2099-02-01  0_2_1_1
892 Bob Lehman  2012-11-01   2099-02-01  1_4_3_1
893 Bob Lehman  2012-05-03   2099-02-01  0_0_2_2

Я хочу сделать такую ​​задачу. Я хочу такую ​​запись, в которой, если сегодня есть между startdate и enddate также на основе типа rec.

В RecType Filed значение хранится как 0_2_1_1 означает повторение этого события каждый второй месяц, первую неделю и третий день.

Так что если событие начинается в 2012-05-01, значит, 1 мая 2012 года, так что теперь повторение события в такой дате, которое выполняет условие повторения, например, тогда оно будет повторяться каждые два месяца, поэтому следующий месяц будет означать, что в июле, 1-й и 3-й день Дата повторения - 2012-07-03 3 июля 2012 года.

Так что это будет повторяться на

2012/07/01
2012/09/02
2012/11/04
2013/01/06
2
nl ja de
@JonathanLeffler Теперь проверьте мой вопрос снова в поле rec_type, теперь данные типа (year_month_week_day) означают, что данные будут повторяться таким образом. если rec_type равно 0_2_1_1, то выходные данные будут повторяться каждые 2 месяца, первая неделя и первый день
добавлено автор AB Vyas, источник
@techdo Да что-то вроде этого, но в последнем аргументе означает день в тот день недели, а не дату, так что, если 1, то в воскресенье, 2 затем в понедельник ...... n, так что 7 означает субботу ....
добавлено автор AB Vyas, источник
@Raj да брат ...
добавлено автор AB Vyas, источник
@Raj да, эта таблица более 1 к записи. и я должен обрабатывать всю запись каждый день
добавлено автор AB Vyas, источник
Это будет ужасно неудобно, независимо от того, какую СУБД вы используете. Это можно сделать; это не будет забавно. Просто анализ дескриптора month_n_w_d_ # no является беспорядочным. Не ясно, что означают поля в версии year_n_x_y_ # no (каждый n-й год в X-м месяце и в y-ый день месяца?). Ваш вопрос может с пользой опускать столбцы «created_date» и «updated_date», поскольку они несущественны для вопроса и будут избегать горизонтальной полосы прокрутки (которая скрывает критический столбец). Возможно, вы тоже можете опустить столбец «url».
добавлено автор Jonathan Leffler, источник
Ваш вопрос «Я хочу такую ​​запись, в которой, если сегодня находится между startdate и enddate, также на основе типа rec». означает, что задача должна выполняться, если выполняются оба условия?
добавлено автор Raj, источник
Насколько велика эта таблица? Я предполагаю, вы должны обрабатывать все записи каждый день, не так ли?
добавлено автор Raj, источник
Для 0_2_1_1 это означает, что каждые 2 месяца, первая неделя и первый день? Итак, в вашем примере это должно быть 2012/07/01 , 2012/09/01 и т. Д. Нет?
добавлено автор TechDo, источник

2 ответы

Наконец я получил свой ответ.

USE [Database]
GO
/****** Object:  UserDefinedFunction [dbo].[getNextDay]    Script Date: 12/28/2012 17:10:19 ******/

SET ANSI_NULLS ON

GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[getNextDay](@SDate datetime, @Rec varchar(max))
returns datetime
as
BEGIN
--Find the next day based on Condition


Declare @SecArg varchar(max)
Declare @NYear varchar(max)
Declare @NMonth varchar(max)
Declare @NWeek varchar(max)
Declare @NDay varchar(max)

select @NYear = substring(@rec,0,CHARINDEX('_',@rec)) 

SET @REC = SUBSTRING(@rec,CHARINDEX('_',@rec)+1,LEN(@REC))

select @NMonth = substring(@rec,0,CHARINDEX('_',@rec)) 

SET @REC = SUBSTRING(@rec,CHARINDEX('_',@rec)+1,LEN(@REC))

select @NWeek = substring(@rec,0,CHARINDEX('_',@rec)) 

SET @REC = SUBSTRING(@rec,CHARINDEX('_',@rec)+1,LEN(@REC))

Declare @NewDate datetime
set @NewDate = @SDate
if (@NYear != 0 or @NYear != '')
begin

    set @SDate = DateAdd(Year,Convert(int,@Nyear),@SDate)
end


if (@NMonth != 0 or @NMonth != '')
begin
    set @SDate = DateAdd(Month,Convert(int,@NMonth),@SDate)
end

    return Convert(varchar, dbo.getWeekDay(Convert(int,@NWeek),Convert(Int,@rec),DATEADD(dd,-(DAY(@SDate)-1),@SDate)),120)
end

Теперь я создал еще одну функцию getWeekDay для поиска дня конкретной недели определенного месяца

USE [Database]
GO
/****** Object:  UserDefinedFunction [dbo].[getWeekDay]    Script Date: 12/28/2012 17:15:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[getWeekDay]( @var_weeknum int, @var_weekday int, @var_date datetime)
returns datetime
as
BEGIN
     declare @cnt int
     declare @startDay int
     declare @DayDiffrence int 
     declare @ReturnDate datetime
     set @cnt = 1
     set @startday =  datepart(dw, dateadd(mm, datediff(mm, 0, @var_Date),0))
     set @DayDiffrence = @var_weekday - @startday
     set @ReturnDate = dateadd(mm, datediff(mm, 0, @var_date),0)

     if(@DayDiffrence > 0)
     begin
              set @ReturnDate = dateadd(d,@DayDiffrence,@ReturnDate)
              set @ReturnDate = dateadd(wk,@var_weeknum - 1,@ReturnDate)
     end
     else
     begin
              set @ReturnDate = dateadd(d,7 - (@DayDiffrence * -1),@ReturnDate)
              set @ReturnDate = dateadd(wk,@var_weeknum - 1,@ReturnDate)
     end

             return @ReturnDate
    end

Теперь, наконец, я получил свой ответ только одним запросом

 select dbo.getNextDay('2012-07-01','0_2_3_3')

 In this my date is 2012-07-01 
 my condition is every 0 year, 2 month, and 3rd week and 3rd dayofweek.

 so this will return 2012-09-18

Благодаря www.google.com и blog.sqlauthority.com а также благодаря моим друзьям Stackoverflow .... :)

2
добавлено

Прежде всего, я настоятельно рекомендую реструктурировать (нормализовать) таблицу для поля rec_type вместо varchar, чтобы быть четырьмя полями tinyint следующим образом: rec_y rec_m rec_w rec_d

И поэтому просто напишите функцию, определенную пользователем, следующим образом:

CREATE FUNCTION GetNextEvent 
(
    @curevent datetime, @rec_y tinyint, @rec_m tinyint, @rec_w tinyint, @rec_d tinyint, @end_date datetime
)
RETURNS datetime AS
BEGIN
    DECLARE @nextevent datetime
    set @nextevent=DATEADD(DAY,@rec_d,DATEADD(WEEK,@rec_w,DATEADD(MONTH,@rec_m,DATEADD(YEAR,@rec_y,@curevent))))
    if @nextevent>@end_date set @nextevent=null
    RETURN @nextevent
END

Затем вы можете написать цикл Cursor, чтобы получить все даты события, если они меньше, чем end_date, в зависимости от вашего требования, которое сохраняется в базе данных в другой таблице при создании и обновлении или просмотре и вычислении по запросу.

0
добавлено
SqlCom.ru - Стиль жизни SQL
SqlCom.ru - Стиль жизни SQL
908 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только MS SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz). Предложения в @sql_ninja

SQL_Ninja
SQL_Ninja
340 участник(ов)

Правила чата - https://t.me/sqlcom/88269 @sqlcom - основной канал (только SQL) @sql_ninja - второй канал (SQL вопросы начального уровня и свободное общение) @Gopnegbot - Викторина по SQL Server (наберите в привате /quiz)