根据开始日期和持续时间查找结束日期 - T-SQL

时间:2016-03-13 05:21:11

标签: sql sql-server tsql date

我有一个包裹表,其中每个包裹包括天数,天数[包括星期日,星期一,...]

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. 待入住日期
  4. 示例:

      

    对于套餐1,从2016年3月13日开始,正确结束日期应为:   03-APR-2016   (10天将是13,14,15,20,21,22,27,28,29 3月,03   四月)

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

    到目前为止,我已经完成了这项工作,但它包括所有7天。

    任何人都可以帮助如何只包含特定日期才能获得正确的到期日期吗?

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

您可以使用Numbers表和日历表执行此操作,我创建了一些使用您的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 pkgid=@packageno ) and date>=@dt
)
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 id=@packageno)

return @expiry
end

如果您不想将alter daysincluded包含为规范化版本,则可能必须使用tally函数执行相同操作并将其添加到cte中

您可以查看日历表here

答案 2 :(得分: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