2016-03-13 4 views
0

У меня есть таблица для пакетов, где каждый пакет состоит из количества дней, дней, включенных [в любое время дня, воскресенье, ...]Начало Окончания на основе даты начала и окончания - T-SQL

Package | Duration | Days Included 
------------------------------------------- 
Package 1 | 10 days | '1,2,3' [Sun, Mon, Tue] 
Package 2 | 15 days | '4,5,6,7' [Wed, Thu, Fri, Sat] 
Package 3 | 30 days | '1,2,3,4,5,6,7' [Sun, Mon, Tue, Wed, Thu, Fri, Sat] 
etc 

Когда клиент выбирает какой-либо пакет (выбрав дату начала), мне нужно рассчитать дату истечения срока действия этого пакета на основании нет. дней и дней, включенных в этот пакет.

Мне нужно создать функцию, в которой будет возвращена Дата истечения срока действия, предоставляющая следующие 3 входа.

  1. Дата начала
  2. Количество дней
  3. дней, которые будут включены

Пример:

для пакета 1, начиная с 13-Mar-2016, Correct Дата окончания должен быть: 03-апр-2016 (10 дней будет 13,14,15,20,21,22,27,28,29 03 марта 2012 года) Apr)

DECLARE @StartDate DATETIME 
DECLARE @NoDays INT 
DECLARE @EndDate DATETIME 
SET @EndDate = DATEADD(DD, @NoDays, @StartDate) 

До сих пор я сделал это, но в том числе все 7 дней.

Может ли кто-нибудь помочь, как только конкретные дни могут быть включены для получения правильной даты истечения срока?

+0

Пожалуйста, объясните, как * дней Включено * работает – har07

+0

Кроме того, оставить правильный ' Пример EndDate при задании определенных «StartDate», «NoDays» и «Days Days» – har07

+0

@ har07 Я отредактировал вопрос одним образцом. Спросите меня, если все еще неясно –

ответ

1

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

---package table 
create table packagetable 
(
id int, 
maxduration int 
) 


insert into packagetable 
select 1,10 


----storing number of days in normalized way 
create table packagedays 
(
pkgid int, 
pkgdays int 
) 

insert into packagedays 
select 1,1 
union all 
select 1,2 

create function dbo.getexpirydate 
(
@packageno int, 
@dt datetime 
) 
returns datetime 
as 
begin 

declare @expiry datetime 
;with cte 
as 
(
select date,row_number() over (order by date) as rn from dbo.calendar 
where wkdno in (select pkgdays from packagedays where [email protected]) and date>[email protected] 
) 
select @expiry= max(Date)+1--after last date of offer add +1 to get next day as expiry date 
from cte 
where rn=(select maxduration from packagetable where [email protected]) 

return @expiry 
end 

, если вы не хотите изменить daysincluded, как нормированную версию, вы, возможно, придется использовать функцию учетный, которая делает то же самое и добавить его в КТР

Вы можете посмотреть календарь настольный here

+0

В основном у меня нормализованная таблица, я упоминаю здесь только для лучшего понимания. Спасибо. Позвольте мне попробовать ваше решение –

+0

вам нужно создать таблицу календаря, прежде чем запускать мое решение – TheGameiswar

+0

http: //www.sqlservercentral .com/blogs/dwainsql/2014/03/30/calendar-tables-in-t-sql/ – TheGameiswar

1
DECLARE @StartDate DATETIME 
DECLARE @NoDays INT 
DECLARE @DaysIncluded VARCHAR(20) 
DECLARE @EndDate DATETIME, @LOOP INT, @Count int 

SET @StartDate = getdate() 
SET @NoDays = 10 
SET @DaysIncluded = '1,2' 
SET @LOOP = @NoDays 


SET @EndDate = @StartDate 

WHILE (@LOOP > 0) 
BEGIN 

SET @EndDate = DATEADD(DD, 1, @EndDate) 
print @EndDate 
Select @Count = Count(1) from dbo.splitstring(@DaysIncluded) where name in (DATEPART(dw,@EndDate)) 

if(@Count > 0) 
BEGIN 
print 'day added' 
SET @LOOP = @LOOP - 1 
END 

END 

если вы хотите функцию dbo.splitstring, пожалуйста, нажмите here

+0

Я не включил текущий день в расчет срока действия, поэтому, если вы хотите включить его, поставьте оператор SET @EndDate = DATEADD (DD, 1, @EndDate) после блока IF – Hasham

+0

Мне нужно только Дата истечения срока взамен :( –

1
DECLARE @StartDate DATETIME = '3/13/2016' 
DECLARE @NoDays INT = 10 
DECLARE @DaysIncluded varchar(50) = '1,2,3,4' 

DECLARE @EndDate DATETIME = DATEADD(d, -1, @StartDate) 

DECLARE @IndexOuter INT = 1 
DECLARE @IndexInner INT = 1 
DECLARE @AuxDate DATETIME 

while @IndexOuter <= @NoDays 
begin 

    set @IndexInner = 1 

    while @IndexInner <= 7 
    begin 
     SET @AuxDate = DATEADD(d, @IndexInner, @EndDate) 

     IF DATEPART(DW, @AuxDate) in (select IntValue from ConvertCsvToInt(@DaysIncluded)) 
     begin 
      set @EndDate = @AuxDate 
      break 
     end 

     set @IndexInner = @IndexInner + 1 
    end 

    print @EndDate 

    set @IndexOuter = @IndexOuter + 1 
end 

select @EndDate 

Чтобы увидеть функцию ConvertCsvToInt click here

Смежные вопросы