【问题标题】:T-SQL : calculate by month and dayT-SQL:按月和日计算
【发布时间】:2017-02-09 23:23:06
【问题描述】:

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

好的,我要做的是正确计算以下 [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]

【问题讨论】:

  • 升级到支持的数据库产品。为什么要尝试修复在不再受支持的数据库引擎上运行的东西?如果需要,您可以获取 SQL Server 2016 的免费版本。
  • 。 .祝你好运。谁记得 SQL Server 2000 支持和不支持什么?
  • 。 .创建一个包含月份定义的表。然后使用此表并连接回您的数据进行计算。
  • 你最大的问题是隐藏在黑暗中......使用 SQL 2000
  • “我不能上班”能不能再含糊一点?你能提供几个输入和期望输出的例子吗?你能解释一下“神奇数字”吗? 5555555?您可能想尝试消除一些繁忙的工作,例如在确定Day(@LeaseFromDate)) = 30 之后计算(30 - day(@LeaseFromDate))+1

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


【解决方案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'

【讨论】:

    猜你喜欢
    • 2010-09-08
    • 2013-02-22
    • 1970-01-01
    • 1970-01-01
    • 2019-10-23
    • 2015-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多