此答案遵循T-SQL格式。我将这个问题概念化为datetime格式中两个日期点之间的线性时间距离之一,将它们称为Time1和Time2;时间1应与您正在处理的“时间上更早”的值(例如出生日期或小部件创建日期或旅程开始日期)对齐,并且时间2应与“时间更新”值(例如快照日期或小部件完成日期或旅程检查点到达日期)。
DECLARE @Time1 DATETIME
SET @Time1 = '12/14/2015'
DECLARE @Time2 DATETIME
SET @Time2 = '12/15/2016'
该解决方案利用简单的测量,转换和计算不同长度的多个循环的串行交点;这里:世纪,十年,年,月,日(感谢玛雅日历的概念!)。感谢一下:我感谢Stack Overflow的其他贡献者,向我展示了我在这个过程中组合起来的一些组件功能。我在这个论坛上积极评价这些。
首先,构建一个水平线,它是世纪,十年,年,月的交点的线性集合,按月递增。为此,使用交叉连接笛卡尔函数。 (认为这是创造,从中我们将为了切两“YYYY-MM”点之间的长度测量距离布):
SELECT
Linear_YearMonths = (centuries.century + decades.decade + years.[year] + months.[Month]),
1 AS value
INTO #linear_months
FROM
(SELECT '18' [century] UNION ALL
SELECT '19' UNION ALL
SELECT '20') centuries
CROSS JOIN
(SELECT '0' [decade] UNION ALL
SELECT '1' UNION ALL
SELECT '2' UNION ALL
SELECT '3' UNION ALL
SELECT '4' UNION ALL
SELECT '5' UNION ALL
SELECT '6' UNION ALL
SELECT '7' UNION ALL
SELECT '8' UNION ALL
SELECT '9') decades
CROSS JOIN
(SELECT '1' [year] UNION ALL
SELECT '2' UNION ALL
SELECT '3' UNION ALL
SELECT '4' UNION ALL
SELECT '5' UNION ALL
SELECT '6' UNION ALL
SELECT '7' UNION ALL
SELECT '8' UNION ALL
SELECT '9' UNION ALL
SELECT '0') years
CROSS JOIN
(SELECT '-01' [month] UNION ALL
SELECT '-02' UNION ALL
SELECT '-03' UNION ALL
SELECT '-04' UNION ALL
SELECT '-05' UNION ALL
SELECT '-06' UNION ALL
SELECT '-07' UNION ALL
SELECT '-08' UNION ALL
SELECT '-09' UNION ALL
SELECT '-10' UNION ALL
SELECT '-11' UNION ALL
SELECT '-12') [months]
ORDER BY 1
然后,将您的时间1和时间2日点到“YYYY -mm'格式(将这些视为整个布料上的坐标切割点)。保留原始日期时间版本的点,以及:
SELECT
Time1 = @Time1,
[YYYY-MM of Time1] = CASE
WHEN LEFT(MONTH(@Time1),1) <> '1' OR MONTH(@Time1) = '1'
THEN (CAST(YEAR(@Time1) AS VARCHAR) + '-' + '0' + CAST(MONTH(@Time1) AS VARCHAR))
ELSE (CAST(YEAR(@Time1) AS VARCHAR) + '-' + CAST(MONTH(@Time1) AS VARCHAR))
END,
Time2 = @Time2,
[YYYY-MM of Time2] = CASE
WHEN LEFT(MONTH(@Time2),1) <> '1' OR MONTH(@Time2) = '1'
THEN (CAST(YEAR(@Time2) AS VARCHAR) + '-' + '0' + CAST(MONTH(@Time2) AS VARCHAR))
ELSE (CAST(YEAR(@Time2) AS VARCHAR) + '-' + CAST(MONTH(@Time2) AS VARCHAR))
END
INTO #datepoints
然后,选择的“YYYY-MM”单元的序号距离,少一个要转换为基数距离(即切一块布从在确定的切点全棉布,并得到其原始测量):
SELECT
d.*,
Months_Between = (SELECT (SUM(l.value) - 1) FROM #linear_months l
WHERE l.[Linear_YearMonths] BETWEEN d.[YYYY-MM of Time1] AND d.[YYYY-MM of Time2])
FROM #datepoints d
Raw Output: 我称这是一个“原始的距离”,因为“YYYY-MM”红衣主教距离的月份部分可能是太多了;需要比较该月份内的每日周期组件,以查看是否应计算上个月的值。在这个例子中,原始输出距离是'12'。但是12/14之前的这个错误是在12/15之前完成的,所以只有11个月的时间已经过去了 - 仅仅一天就要过了第12个月。因此,我们必须引入月内一天的周期才能得出最终答案。插入之间的“月,日”位置比较,以确定是否最新的日期点一个月名义上计算,或不:
SELECT
d.*,
Months_Between = (SELECT (SUM(l.value) - 1) FROM AZ_VBP.[MY].[edg_Linear_YearMonths] l
WHERE l.[Linear_YearMonths] BETWEEN d.[YYYY-MM of Time1] AND d.[YYYY-MM of Time2])
+ (CASE WHEN DAY(Time1) < DAY(Time2)
THEN -1
ELSE 0
END)
FROM #datepoints d
Final Output: “11”的正确答案是,现在我们的产量。所以,我希望这有助于。谢谢!
2009-01-31至2009-02-28。这是0或1个整月吗? – 2009-07-09 23:26:55
这应该是0 – oscarkuo 2009-07-09 23:48:53