T-SQL:按月和日计算

时间:2016-10-01 13:57:38

标签: sql sql-server tsql sql-server-2000

我认为我必须过度复杂化。首先,我非常感谢大家帮助我。

好吧我正在尝试做的是正确计算以下[租户专业租赁自定义]并且它无法正常工作。我无法弄清楚如何让它发挥作用。

规则是:

  1. 所有月份均分为30天......专业租金计算(包括二月份)

  2. 当天有31天且合约在当天的第31天签署的合约将是免费的。所以只包括下个月的租金。 (T.sRent)

  3. 在第31天和第31天之前签订合同的月份按比例计算天数计算......即使它被除以30天。

  4. 2月即使有28天或29天,也会计算好像有30天。这个月的最后一天也只包括下个月的租金。

  5. 每月30日和31日按比例分配下个月的租金。

  6. 我可以构建一个处理此问题的函数。

    这是一个我无法工作的简化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]
    

1 个答案:

答案 0 :(得分:1)

我对此非常猜测......

我假设+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'