T-SQL : 按月和日计算

T-SQL : calculate by month and day

我想我必须把这个复杂化了。首先我想非常感谢大家帮助我。

好的,所以我想做的是正确计算以下 [Tenant Pro-Rated Rent Custom],但它无法正常工作。我不知道如何让它工作。

规则是:

  1. 所有月份均分为30天...用于Pro Rated租金计算(包括2月)

  2. 月份凡是有31天并且在第31天签合同的那一天就可以免签了。所以只包括下个月的租金。 (T.sRent )

  3. 有第 31 天并且在 31 日前签订合同的月份,第 31 天包含在按比例计算的天数中...即使它除以 30 天。

  4. 2 月虽然有 28 或 29 天,但它被计算为好像有 30 天。另外每月的最后一天只包括下个月的租金。

  5. 每个月的 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'