考虑到 SQL 中的正确月数,我该如何进行每月计算?
How do I do this monthly calculation taking into account the correct number of months in SQL?
DECLARE @InputPeriodStart DATE = '1/1/2014'
DECLARE @InputPeriodEnd DATE = '12/31/2014'
ROUND(CONVERT(DECIMAL, DATEDIFF(dd, @InputPeriodStart, @InputPeriodEnd)) / 30, 1) AS DECIMAL(18, 2))
这里的问题是不是每个月都有 30 天。那么我怎样才能使这个计算正常工作呢?
我需要删除 ROUND()
,然后将 30 替换为每个月的实际天数。我不确定该怎么做。
这是您要找的吗?
DATEDIFF(mm, @InputPeriodStart, @InputPeriodEnd))
如果你想做一些更奇怪的事情,比如调整你 "periodstart" 所在月份的天数 - 那么你将进入一些奇怪的领域,但它仍然是可能的。只需留下评论即可指定。
编辑:
看看这个 SQLFiddle:
http://sqlfiddle.com/#!6/a1463/7
这实现了我最后一条评论的内容。
这个答案主要是关于 datediff()
的警告。
对于您的示例,datediff(day, @InputPeriodStart, @InputPeriodEnd)
returns 11 而不是 12。这是因为 datediff()
计算 月 之间的边界数两个值。
我猜你想要 12 个。你可以通过两种方式获得它:
DATEDIFF(month, @InputPeriodStart, @InputPeriodEnd)) + 1
或:
DATEDIFF(month, @InputPeriodStart, DATEADD(day, 1, @InputPeriodEnd))
或者,如果你不关心具体是哪一天,你也可以对年月值进行算术运算:
(1 + (YEAR(@InputPeriodEnd) * 12 + MONTH(@InputPeriodEnd)) -
(YEAR(@InputPeriodEnd) * 12 + MONTH(@InputPeriodStart))
)
DATEDIFF()
的语义可能有点混乱。该定义适用于秒数(通常)和使用 day
作为日期。在其他时候,它可能会导致难以检测和解决的差一错误。
DECLARE @InputPeriodStart DATE = '1/1/2014'
DECLARE @InputPeriodEnd DATE = '12/31/2014'
ROUND(CONVERT(DECIMAL, DATEDIFF(dd, @InputPeriodStart, @InputPeriodEnd)) / 30, 1) AS DECIMAL(18, 2))
这里的问题是不是每个月都有 30 天。那么我怎样才能使这个计算正常工作呢?
我需要删除 ROUND()
,然后将 30 替换为每个月的实际天数。我不确定该怎么做。
这是您要找的吗?
DATEDIFF(mm, @InputPeriodStart, @InputPeriodEnd))
如果你想做一些更奇怪的事情,比如调整你 "periodstart" 所在月份的天数 - 那么你将进入一些奇怪的领域,但它仍然是可能的。只需留下评论即可指定。
编辑:
看看这个 SQLFiddle:
http://sqlfiddle.com/#!6/a1463/7
这实现了我最后一条评论的内容。
这个答案主要是关于 datediff()
的警告。
对于您的示例,datediff(day, @InputPeriodStart, @InputPeriodEnd)
returns 11 而不是 12。这是因为 datediff()
计算 月 之间的边界数两个值。
我猜你想要 12 个。你可以通过两种方式获得它:
DATEDIFF(month, @InputPeriodStart, @InputPeriodEnd)) + 1
或:
DATEDIFF(month, @InputPeriodStart, DATEADD(day, 1, @InputPeriodEnd))
或者,如果你不关心具体是哪一天,你也可以对年月值进行算术运算:
(1 + (YEAR(@InputPeriodEnd) * 12 + MONTH(@InputPeriodEnd)) -
(YEAR(@InputPeriodEnd) * 12 + MONTH(@InputPeriodStart))
)
DATEDIFF()
的语义可能有点混乱。该定义适用于秒数(通常)和使用 day
作为日期。在其他时候,它可能会导致难以检测和解决的差一错误。