基于开始日期和持续时间查找结束日期-T-SQL
我有一个包裹表,其中每个包裹包括天数,包括天数[周日、周一等任何一天]基于开始日期和持续时间查找结束日期-T-SQL,sql,sql-server,tsql,date,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,
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个输入
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,请单击
如果您想要函数dbo.splitstring,请单击您可以使用数字表和日历表,我已经创建了一些使用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
如果您不想将alterdaysincluded作为规范化版本,那么您可能必须使用tally函数,该函数也可以这样做,并将其添加到cte中
您可以看到日历表您可以使用数字表和日历表,我已经创建了一些测试数据,使用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
如果您不想将alterdaysincluded作为规范化版本,那么您可能必须使用tally函数,该函数也可以这样做,并将其添加到cte中
您可以查看日历表DECLARE@StartDate DATETIME='3/13/2016'
声明@NoDays INT=10
声明@DaysIncluded varchar(50)='1,2,3,4'
声明@enddatetime=DATEADD(d,-1,@StartDate)
声明@IndexOuter INT=1
声明@IndexInner INT=1
声明@AuxDate DATETIME
而@IndexOuterDECLARE@StartDate DATETIME='3/13/2016'
声明@NoDays INT=10
声明@DaysIncluded varchar(50)='1,2,3,4'
声明@enddatetime=DATEADD(d,-1,@StartDate)
声明@IndexOuter INT=1
声明@IndexInner INT=1
声明@AuxDate DATETIME
请在@IndexOuter中解释天数是如何工作的,并给出一个正确的EndDate
示例,给出特定的StartDate
,NoDays
,以及天数Included@har07我用一个样本编辑了这个问题。询问我是否仍不清楚请解释天数是如何包含的,并给出一个正确的结束日期
示例,给出特定的开始日期
,节点日期
,以及天数Included@har07我用一个样本编辑了这个问题。问我是否仍然不清楚我有标准化的表,我在这里提到只是为了更好地理解。谢谢让我试试你的解决方案在运行我的解决方案之前,你需要先创建日历表。我认为这种逻辑比while循环(在其他答案中)更好。然而,日历表的创建是唯一的额外工作。是的,我们必须创建一次,这是无效的基本上我有规范化的表,我在这里提到只是为了更好地理解。谢谢让我试试你的解决方案在运行我的解决方案之前,你需要先创建日历表。我认为这种逻辑比while循环(在其他答案中)更好。但是,日历表的创建是唯一的额外工作。是的,我们必须创建一次,而且它是无效的。我没有在到期计算中包括当天,因此如果您想包括这一天,请将语句SET@EndDate=DATEADD(DD,1,@EndDate)放在if块之后,我只需要到期日期作为回报:(我没有将当前日期包括在到期计算中,因此如果您想将其包括在内,请将语句集@EndDate=DATEADD(DD,1,@EndDate)放在if块之后,作为回报,我只需要到期日期:(
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