T-SQL : 按月和日计算
T-SQL : calculate by month and day
我想我必须把这个复杂化了。首先我想非常感谢大家帮助我。
好的,所以我想做的是正确计算以下 [Tenant Pro-Rated Rent Custom],但它无法正常工作。我不知道如何让它工作。
规则是:
所有月份均分为30天...用于Pro Rated租金计算(包括2月)
月份凡是有31天并且在第31天签合同的那一天就可以免签了。所以只包括下个月的租金。 (T.sRent )
有第 31 天并且在 31 日前签订合同的月份,第 31 天包含在按比例计算的天数中...即使它除以 30 天。
2 月虽然有 28 或 29 天,但它被计算为好像有 30 天。另外每月的最后一天只包括下个月的租金。
每个月的 30 日和 31 日按比例计算下个月的租金。
我可以构建一个函数来处理这个问题。
这是一个简化的 SQL 我无法上班的声明:
Declare @LeaseFromDate as DateTime
Declare @Rent as decimal (10,2)
Set @LeaseFromDate = '9/10/2016'
Set @Rent = '1000.00'
Select
Case
--When isnull(DATEDIFF(DAY,DATEADD(DAY, 0, DATEADD(m, ((year(@LeaseFromDate) - 1900) * 12) + month(@LeaseFromDate) - 1, 0)),
--DATEADD(DAY, 0, DATEADD(m, ((year(@LeaseFromDate) - 1900) * 12) + month(@LeaseFromDate), 0))
-- ) - day(@LeaseFromDate),0) = false
-- Then 0
When (month(@LeaseFromDate) in (1,3,5,7,8,10,12) and (Day(@LeaseFromDate)) = 31) -- get this day free just add next months rent to the prorate
Then CAST(ROUND((@Rent / 30),2) AS decimal(10,2))+3333333
When (month(@LeaseFromDate) in (1,3,5,7,8,10,12) and (Day(@LeaseFromDate)) = 30) --Add Next Months rent to the prorate
Then CAST( ( (ROUND((@Rent / 30) * ((30 - day(@LeaseFromDate))+1),2)) + @Rent ) AS decimal(10,2) )+4444444
When (month(@LeaseFromDate) in (1,3,5,7,8,10,12)) --Just Prorate the rent
Then CAST(ROUND((@Rent / 30) * ((30 - day(@LeaseFromDate))+1),2) AS decimal(10,2))+5555555
When ((Day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@LeaseFromDate)+1,0)))) <= (Day(@LeaseFromDate)) and month(@LeaseFromDate) in (2,4,6,9,11))
THEN CAST( ( (ROUND((@Rent / 30) * ((30 - day(@LeaseFromDate))+1),2)) + @Rent ) AS decimal(10,2) )+1111111
When (month(@LeaseFromDate) in (2,4,6,9,11) and (Day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@LeaseFromDate)+1,0)))) <= (Day(@LeaseFromDate)-1))
THEN CAST(ROUND((@Rent / 30) * ((30 - day(@LeaseFromDate))+1),2) AS decimal(10,2))+2222222
Else 0
end as [Tenant Pro-Rated Rent Custom]
我对此进行了相当大胆的猜测...
我假设 +111111 和 +222222 只是为了让您可以看到哪个案例正在触发...如果不是,我将删除此答案。
我将其分解为确定月份中的第几天和签署日期,然后还有多少天用于按比例分配。如果他们在 31 日签署,我们什么都不做,如果他们在 31 日之前签署,我们会增加一天。如果净值超过 30,我们就将其设置为 30。
然后我根据签约日期确定是否需要添加下个月的租金。
一旦你掌握了所有这些,计算就非常简单了。
/* Set User Variables */
DECLARE @LeaseFromDate DATETIME, @Rent MONEY
SET @LeaseFromDate = '2016-10-30'
SET @Rent = 1000.00
/* Determine Key Values */
DECLARE @DaysLeftInMonth INT, @LastOfMonth DATETIME, @DaysInMonth INT
SET @LastOfMonth = DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,0,@LeaseFromDate)+1,0))
SET @DaysInMonth = DATEPART(DD,@LastOfMonth)
SET @DaysLeftInMonth = DATEPART(DD,@LastOfMonth)-DATEPART(DD,@LeaseFromDate)
/* Calculate Days Left in Month to Prorate */
DECLARE @DaysToProrate INT, @AddNextMonth BIT
SET @DaysToProrate = @DaysLeftInMonth
/* If 31 days in month, and leasing from 31st, free day*/
IF DATEPART(DD,@LastOfMonth)=31 AND DATEPART(DD,@LeaseFromDate)=31
PRINT 'Free Day'
/* If 31 days in month, and leasing before 31st add a day */
IF DATEPART(DD,@LastOfMonth)=31 AND DATEPART(DD,@LeaseFromDate)<31
SET @DaysToProrate = @DaysToProrate+1
/* If we're over 30 days, reduce to 30 days */
IF @DaysToProrate > 30 SET @DaysToProrate=30
/* If renting on 30/31 of month or from Feb28/29 then add a month to rent calculation */
IF DATEPART(DD,@LeaseFromDate) IN (30,31) OR (DATEPART(MM,@LeaseFromDate)=2 AND DATEPART(DD,@LeaseFromDate) IN (28,29))
SET @AddNextMonth = 1
ELSE
SET @AddNextMonth = 0
/* Show our Values */
--SELECT @DaysToProrate, @AddNextMonth
/* Do the Math */
SELECT CONVERT(DECIMAL(10,2),(@Rent/30.00)*@DaysToProrate), 'Prorated Amount'
UNION
SELECT CONVERT(DECIMAL(10,2),@Rent*@AddNextMonth), 'Next Months Inclusion'
/* Output */
SELECT CONVERT(DECIMAL(10,2),
((@Rent/30.00)*@DaysToProrate)
+ (@Rent*@AddNextMonth)), 'Total Due At Signing'
我想我必须把这个复杂化了。首先我想非常感谢大家帮助我。
好的,所以我想做的是正确计算以下 [Tenant Pro-Rated Rent Custom],但它无法正常工作。我不知道如何让它工作。
规则是:
所有月份均分为30天...用于Pro Rated租金计算(包括2月)
月份凡是有31天并且在第31天签合同的那一天就可以免签了。所以只包括下个月的租金。 (T.sRent )
有第 31 天并且在 31 日前签订合同的月份,第 31 天包含在按比例计算的天数中...即使它除以 30 天。
2 月虽然有 28 或 29 天,但它被计算为好像有 30 天。另外每月的最后一天只包括下个月的租金。
每个月的 30 日和 31 日按比例计算下个月的租金。
我可以构建一个函数来处理这个问题。
这是一个简化的 SQL 我无法上班的声明:
Declare @LeaseFromDate as DateTime
Declare @Rent as decimal (10,2)
Set @LeaseFromDate = '9/10/2016'
Set @Rent = '1000.00'
Select
Case
--When isnull(DATEDIFF(DAY,DATEADD(DAY, 0, DATEADD(m, ((year(@LeaseFromDate) - 1900) * 12) + month(@LeaseFromDate) - 1, 0)),
--DATEADD(DAY, 0, DATEADD(m, ((year(@LeaseFromDate) - 1900) * 12) + month(@LeaseFromDate), 0))
-- ) - day(@LeaseFromDate),0) = false
-- Then 0
When (month(@LeaseFromDate) in (1,3,5,7,8,10,12) and (Day(@LeaseFromDate)) = 31) -- get this day free just add next months rent to the prorate
Then CAST(ROUND((@Rent / 30),2) AS decimal(10,2))+3333333
When (month(@LeaseFromDate) in (1,3,5,7,8,10,12) and (Day(@LeaseFromDate)) = 30) --Add Next Months rent to the prorate
Then CAST( ( (ROUND((@Rent / 30) * ((30 - day(@LeaseFromDate))+1),2)) + @Rent ) AS decimal(10,2) )+4444444
When (month(@LeaseFromDate) in (1,3,5,7,8,10,12)) --Just Prorate the rent
Then CAST(ROUND((@Rent / 30) * ((30 - day(@LeaseFromDate))+1),2) AS decimal(10,2))+5555555
When ((Day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@LeaseFromDate)+1,0)))) <= (Day(@LeaseFromDate)) and month(@LeaseFromDate) in (2,4,6,9,11))
THEN CAST( ( (ROUND((@Rent / 30) * ((30 - day(@LeaseFromDate))+1),2)) + @Rent ) AS decimal(10,2) )+1111111
When (month(@LeaseFromDate) in (2,4,6,9,11) and (Day(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@LeaseFromDate)+1,0)))) <= (Day(@LeaseFromDate)-1))
THEN CAST(ROUND((@Rent / 30) * ((30 - day(@LeaseFromDate))+1),2) AS decimal(10,2))+2222222
Else 0
end as [Tenant Pro-Rated Rent Custom]
我对此进行了相当大胆的猜测...
我假设 +111111 和 +222222 只是为了让您可以看到哪个案例正在触发...如果不是,我将删除此答案。
我将其分解为确定月份中的第几天和签署日期,然后还有多少天用于按比例分配。如果他们在 31 日签署,我们什么都不做,如果他们在 31 日之前签署,我们会增加一天。如果净值超过 30,我们就将其设置为 30。
然后我根据签约日期确定是否需要添加下个月的租金。
一旦你掌握了所有这些,计算就非常简单了。
/* Set User Variables */
DECLARE @LeaseFromDate DATETIME, @Rent MONEY
SET @LeaseFromDate = '2016-10-30'
SET @Rent = 1000.00
/* Determine Key Values */
DECLARE @DaysLeftInMonth INT, @LastOfMonth DATETIME, @DaysInMonth INT
SET @LastOfMonth = DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,0,@LeaseFromDate)+1,0))
SET @DaysInMonth = DATEPART(DD,@LastOfMonth)
SET @DaysLeftInMonth = DATEPART(DD,@LastOfMonth)-DATEPART(DD,@LeaseFromDate)
/* Calculate Days Left in Month to Prorate */
DECLARE @DaysToProrate INT, @AddNextMonth BIT
SET @DaysToProrate = @DaysLeftInMonth
/* If 31 days in month, and leasing from 31st, free day*/
IF DATEPART(DD,@LastOfMonth)=31 AND DATEPART(DD,@LeaseFromDate)=31
PRINT 'Free Day'
/* If 31 days in month, and leasing before 31st add a day */
IF DATEPART(DD,@LastOfMonth)=31 AND DATEPART(DD,@LeaseFromDate)<31
SET @DaysToProrate = @DaysToProrate+1
/* If we're over 30 days, reduce to 30 days */
IF @DaysToProrate > 30 SET @DaysToProrate=30
/* If renting on 30/31 of month or from Feb28/29 then add a month to rent calculation */
IF DATEPART(DD,@LeaseFromDate) IN (30,31) OR (DATEPART(MM,@LeaseFromDate)=2 AND DATEPART(DD,@LeaseFromDate) IN (28,29))
SET @AddNextMonth = 1
ELSE
SET @AddNextMonth = 0
/* Show our Values */
--SELECT @DaysToProrate, @AddNextMonth
/* Do the Math */
SELECT CONVERT(DECIMAL(10,2),(@Rent/30.00)*@DaysToProrate), 'Prorated Amount'
UNION
SELECT CONVERT(DECIMAL(10,2),@Rent*@AddNextMonth), 'Next Months Inclusion'
/* Output */
SELECT CONVERT(DECIMAL(10,2),
((@Rent/30.00)*@DaysToProrate)
+ (@Rent*@AddNextMonth)), 'Total Due At Signing'