如果我正确阅读了您的问题,那么您实际上无法使用上述包含可计费和不可计费天表的解决方案,因为除非整个月都被预订,否则 31 日是可计费的。
我认为这可能是用户定义函数的工作。从开始日期所在的月份开始,到结束日期所在的月份结束。
CREATE FUNCTION dbo.FN_BillableDays (@StartDate date, @EndDate date)
returns int
AS
BEGIN
IF @StartDate > @EndDate
BEGIN
return null --Error
END
DECLARE @Next date
DECLARE @MonthStart date
DECLARE @MonthEnd date
DECLARE @NextMonthStart date
DECLARE @n int =0
SET @Next = @StartDate
SET @MonthStart = DATEADD(day,1-DAY(@Next),@Next)
SET @NextMonthStart = DATEADD(month,1,@MonthStart )
SET @MonthEnd = DATEADD(day,-1,@NextMonthStart)
WHILE DATEDIFF(month,@Next,@EndDate) >0
BEGIN
SET @n = @n +
CASE
WHEN DAY(@next) = 1 AND DAY(@MonthEnd) = 31 THEN 30
WHEN DAY(@next) = 1 THEN DAY(@MonthEnd)
ELSE 1+DAY(@MonthEnd) -DAY(@next) END
SET @MonthStart = @NextMonthStart
SET @NextMonthStart = DATEADD(month,1,@MonthStart )
SET @MonthEnd = DATEADD(day,-1,@NextMonthStart)
SET @Next = @NextMonthStart
END
--Month of the EndDate
SET @n = @n +
CASE
WHEN DAY(@next) = 1 AND DAY(@EndDate) = 31 THEN 29
WHEN DAY(@next) = 1 THEN DAY(@EndDate)-1
ELSE DAY(@MonthEnd) -DAY(@EndDate) END
return @n
END
我尝试了一些测试日期
SELECT
b.BookingID,
b.StartDate,
b.EndDate,
dbo.FN_BillableDays (b.StartDate,b.EndDate) AS BillableDays
FROM dbo.Booking b
得到了以下
BookingID StartDate EndDate BillableDays
----------- ---------- ---------- ------------
1 2013-12-31 2014-01-02 2
2 2013-12-31 2014-01-30 30
3 2014-01-01 2014-01-30 29
4 2014-01-01 2014-01-31 29
5 2014-01-01 2014-02-01 30
6 2014-01-01 2014-02-02 31
7 2014-02-02 2014-02-01 NULL
(7 row(s) affected)
这符合我对您想要实现的逻辑的理解,但您可能想要调整最后一个月的天数。如果他们在 31 日离开,您想免费给他们最后一晚(30 日至 31 日)吗?
如果您不这样做,请删除该行
当 DAY(@next) = 1 AND DAY(@EndDate) = 31 THEN 29