[英]Find End Date based on Start date and Duration - T-SQL
I have a table for packages, where each package consists of Number of Days, Days included [any day(s) Sunday, Monday, ... ] 我有一个包装表,其中每个包装都包括天数,包括的天数[星期日,星期一,...的任何一天]
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
When customer selects any package (selecting the start date), I need to calculate the expiry date of that package based on the no. 当客户选择任何包装时(选择开始日期),我需要根据编号计算该包装的到期日期。 of days and days included in that package. 套餐中包含的天数和天数。
I need to create a function in which will return the Expiry Date providing the following 3 inputs. 我需要创建一个函数,该函数将返回提供以下3个输入的到期日期 。
Example: 例:
For Package 1, starting from 13-Mar-2016, Correct End Date should be: 03-Apr-2016 (10 days would be 13,14,15,20,21,22,27,28,29 March, 03 Apr) 对于套餐1,从2016年3月13日开始,正确的结束日期应为:2016年4月3日(10天为3月14日,13月14、15、20、21、22、27、28、29、4月3日)
DECLARE @StartDate DATETIME
DECLARE @NoDays INT
DECLARE @EndDate DATETIME
SET @EndDate = DATEADD(DD, @NoDays, @StartDate)
So far I have done this, but it is including all 7 days. 到目前为止,我已经做到了,但这包括了全部7天。
Can anybody help how only the specific days can be included to get the correct expiry date? 有人可以帮忙如何仅包含特定日期以获取正确的到期日期吗?
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
if you want the function dbo.splitstring, please click here 如果您需要功能dbo.splitstring,请单击此处
You can do it with Numbers table and calendar table,i have created some test data which uses normalized version of your packagedays table. 您可以使用Numbers表和Calendar表来执行此操作,我创建了一些测试数据,这些数据使用了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
if you don't want alter daysincluded as normalized version,you might have to use tally function which does the same and add it in cte 如果您不希望将变更天数作为归一化版本包括在内,则可能必须使用具有相同功能的计数功能并将其添加到cte中
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
To see ConvertCsvToInt function click here 要查看ConvertCsvToInt函数, 请单击此处
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.