需求:
1. 换房时,要选新房间,新房间的价格根据老房间的租期长短(是否长租)来决定是否加价;
2. 新房间的合同开始日期即为换房当日,合同结束日期为老合同房费结束日;
3. 新房间的这段时间内的房费需要单独计算(因为这段区间不一定是整数个月)
比如:
2016-05-10~2016-08-20 房费2000
2016-05-10~2016-06-09 1个整月 2000
2016-06-10~2016-07-09 1个整月 2000
2016-07-10~2016-08-09 1个整月 2000
2016-08-10~2016-08-20 [8.10~8.20] 共21天 2000/31*21
计算逻辑:
零碎天数的房费:房价/计费开始日所在月份的天数计费天数,其中计费开始日所在月份的天数不一定*等于计费天数
整月房费逻辑:每月房费 or 房价/计费开始日所在月份的天数*计费天数,其中计费开始日所在月份天数=计费天数
可参考sql中的注释
declare @startdate datetime
declare @enddate datetime
declare @contractprice decimal
declare @systemprice decimal
declare @datediff int
declare @OldcontractNo varchar(20)
declare @leftrentdays int
declare @days int
declare @days1 int
declare @days2 int
declare @day int
declare @PayPrice decimal(18,2)
declare @RentPayEndDate datetime
declare @MAdd int
declare @lastBeginTime datetime
declare @Lastdays int
declare @diff int
-----------------------------------------------------查询各项数据--------------------------------------------------
set @OldcontractNo = 'R160001709'
--查询门店房间系统价
set @systemprice = (
select top 1 OriginalMonthPrice from RoomPricePlan
where StoreID = 'SHOP055'
and RoomNo = '515'
order by EndDate,StartDate desc
)
select @systemprice '系统价'
--查询老合同租金到期日
select @RentPayEndDate = RentPayEndDate from ContractRoom
where ContractID = @OldcontractNo
select @RentPayEndDate as '租金到期日'
--计算出老合同入住月数
set @datediff = (
select datediff(M,ArriveDate,DepartDate) from ContractRoom
where ContractID = @OldcontractNo
)
select @datediff '老合同入住月数'
--设置房价
set @contractprice = @systemprice
if @datediff < 6
set @contractprice = @systemprice*1.1
select @contractprice as '合同价'
------------------------------------------------计算各项数据---------------------------------------------------------
--计算当前退房日期距离租金到期日之间的天数
set @leftrentdays = (
select datediff(d,CONVERT(char(10),getdate(),126),RentPayEndDate)+ 1 from ContractRoom
where ContractID = @OldcontractNo
)
select @leftrentdays as '退房日到租金到期日的天数leftrentdays'
--计算租金到期日所在月的天数:如 12月 31天
set @days1 = (select datediff(dd , @RentPayEndDate , dateadd(mm, 1, @RentPayEndDate)))
select @days1 as '租金到期月的天数days1'
--计算租金到期日所在月的上一个月的天数:如 11月 30天
set @days2 = (select datediff(dd , dateadd(M,-1,@RentPayEndDate) , dateadd(mm, 1, dateadd(M,-1,@RentPayEndDate))))
select @days2 as '租金到期月上个月的天数days2'
--计算换房当日所在月数的天数
set @days = (select datediff(dd , GETDATE() , dateadd(mm, 1, GETDATE())))
select @days '换房当月的天数days'
--计算最后一阶段费用开始时间
set @lastBeginTime = (
select DATEADD(M,DATEDIFF(M,GETDATE(),@RentPayEndDate),GETDATE())
)
select @lastBeginTime as '最后零头开始时间'
--设置最后计算房费日子所在月的天数
set @day = (select datediff(dd , @lastBeginTime , dateadd(mm, 1, @lastBeginTime)))
select @day as '最后计算房费日子所在月的天数'
--差值
set @diff = (
select DATEDIFF(M,GETDATE(),@RentPayEndDate)
)
select @diff as '租金到期月与换房当月相差的月数diff'
--select DATEDIFF(M,GETDATE(),'2016-12-14')
--最后一个零数天数
set @Lastdays = (
select DATEDIFF(D,DATEADD(M,@diff,GETDATE()),@RentPayEndDate) + 1
)
--持续的整月月数
set @MAdd =@diff
----------------------------------------------------计算新房间费用逻辑------------------------------------------------------------
if @Lastdays <=0
set @MAdd = @diff - 1
set @Lastdays = (select DATEDIFF(D,DATEADD(M,@MAdd,GETDATE()),@RentPayEndDate) + 1
)
select @MAdd as '整月月数Madd'
select @Lastdays '新房间房租计算天数lastdays'
if (@leftrentdays <= @days )
set @PayPrice = (
select cast(@contractprice/@days * @leftrentdays as decimal(10,2)))
--else if DATEPART(D,@RentPayEndDate) < DATEPART(D,GETDATE())
-- set @PayPrice =(
-- select @contractprice * @MAdd + cast(@contractprice/@days2 * @Lastdays as decimal(10,2)))
else
set @PayPrice =(
select @contractprice * @MAdd + cast(@contractprice/@day * @Lastdays as decimal(10,2)))
select @PayPrice as '新房间应付房租'
主要的知识点:
a. 计算租金到期日所在月的天数:如 12月 31天:
select datediff(dd , @RentPayEndDate , dateadd(mm, 1, @RentPayEndDate))
b. 计算租金到期日所在月的上一个月的天数:如 11月 30天
select datediff(dd , dateadd(M,-1,@RentPayEndDate) , dateadd(mm, 1, dateadd(M,-1,@RentPayEndDate)))
c. datepart()
DATEPART(D,@RentPayEndDate)
主要还是用到 DateAdd(),DateDiff(),DatePart(),以及相互的嵌套使用。
可参考: Actual Practice : DATEADD & DATEDIFF in my work - 1
孰能生巧,多练习,多使用。再不行,Google和baidu!