我的查询如下:
SELECT DATEDIFF(MONTH, convert(datetime,'01/01/2015',103),convert(datetime,'15/02/2015',103) )
我只需要1个月就可以得到结果。
我需要1.5个月才能得到结果。 (指1个月15天)。
我怎样才能得到输出?
试试这个,它会计算出一个月“已使用”的准确百分比。它应该适用于所有日期。
DECLARE @from date = '2015-01-01'
DECLARE @to date = '2015-02-15'
SELECT
datediff(month, @from, @to) - 1 +
1-1.0*(day(@from)-1)/ day(dateadd(m, datediff(m,-1, @from), -1))
+ 1.0*(day(@to)-1)/ day(dateadd(m, datediff(m,-1, @to), -1))
结果:
1.5
请注意
from date = '2015-03-02'
to date = '2015-04-02'
将在 1.001075268817 中给出比 1 稍高的结果,因为在“from”之前经过的三月份的百分比比“to”之前经过的四月的百分比要小
用这个代替:
SELECT DATEDIFF(d, convert(datetime,'01/01/2015',103),
convert(datetime,'15/02/2015',103) ) / 30.0
使用 d
代替 month
来获取天数。然后除以 30 即可得到所需的结果。
注意,您必须使用
30.0
而不是 30
以避免整数除法。
这将是更正确的解决方案:
SELECT DATEDIFF(m, CONVERT(DATETIME, '01/01/2015', 103),
CONVERT(DATETIME, '15/02/2015', 103)) +
DATEPART(DAY, CONVERT(DATETIME, '15/02/2015', 103)) / 30.0
显示差异:
SELECT DATEDIFF(d, CONVERT(DATETIME, '01/01/2015', 103),
CONVERT(DATETIME, '15/03/2015', 103)) / 30.0
2.433333
和
SELECT DATEDIFF(m, CONVERT(DATETIME, '01/01/2015', 103),
CONVERT(DATETIME, '15/03/2015', 103)) +
DATEPART(DAY, CONVERT(DATETIME, '15/03/2015', 103)) / 30.0
2.500000
更准确地说,您可以不除以 30.0,而可以除以上个月的天数:
SELECT DATEDIFF(m, CONVERT(DATETIME, '01/01/2015', 103),
CONVERT(DATETIME, '15/02/2015', 103)) +
(DATEPART(DAY, CONVERT(DATETIME, '15/02/2015', 103))
/ (1.0*DATEDIFF(day, CONVERT(DATETIME, '15/02/2015', 103), dateadd(month, 1, CONVERT(DATETIME, '15/02/2015', 103)))))
1.53571428571428
编辑:
如果 StartDate 不是从第一天开始,那么这个版本将无法工作!然后坚持其他用户之一的回答。
改进之前的答案。
要计算月数,可以将其分为三部分。从月初到月末的部分月份、整个月份以及最后一个月的部分内容。
DECLARE @STARTDATE DATETIME = CONVERT(DATETIME, '22/01/2015', 103)
DECLARE @ENDDATE DATETIME = CONVERT(DATETIME, '15/03/2015', 103)
SELECT -- Whole months
DATEDIFF(m, @STARTDATE, @ENDDATE) - 1
+
-- Part of the month at beginning of the period
(1.0*((DAY(EOMONTH(@STARTDATE))) - DATEPART(DAY, @STARTDATE) + 1)
/ DAY(EOMONTH(@STARTDATE))) -- Number of days in first month
+
-- Part of the month at the end of the period
(1.0*DATEPART(DAY, @ENDDATE)
/ DAY(EOMONTH(@ENDDATE))) -- Number of days in last month
一个月的天数可以通过两种方式计算:
DAY(EOMONTH(@DATE)))
或
(DATEDIFF(day, @DATE, dateadd(month, 1, @DATE)))
试试这个:
SELECT DATEDIFF(d, convert(datetime,'01/01/2015',103),
convert(datetime,'15/02/2015',103) ) / 30.0
即,您需要从 DATEDIFF 获取天数而不是月份,然后将其除以 30 以获得所需的输出。
尝试以下查询来获取月份和日期:
DECLARE @from date = '2015-01-01'
DECLARE @to date = '2015-03-2'
DECLARE @castdate date= CAST(CAST(datePart(year,@to) AS nvarchar(100)) + '-' + CAST(datePart(month,@to) AS nvarchar(100)) + '-' + CAST(datePart(day,@from) AS nvarchar(100)) AS DATE);
DECLARE @TotalDays int= datediff(day,@from,@to);
DECLARE @MonthDays int= datediff(day,@from,@castdate);
print cast((datediff(month,@from,@castdate)) as nvarchar(100))+'.'+ convert(nvarchar(150),(@TotalDays-@MonthDays))
我想分享我复杂的实现函数,用于计算具有浮点输出的日期之间的持续时间(以月为单位)。也许,它可以帮助某人。 !注意它是为 mariadb 10.3 编写的,因此 TIMESTAMPDIFF 的工作方式与 mysql-server 中的 datediff 不同
DELIMITER //
DROP FUNCTION IF EXISTS leap_year;
DROP FUNCTION IF EXISTS date_diff_in_months;
CREATE FUNCTION leap_year(date DATE) RETURNS BOOLEAN
BEGIN
RETURN IF(YEAR(date) % 4 = 0, TRUE, FALSE);
END;
CREATE FUNCTION date_diff_in_months(startDate DATE, endDate DATE) RETURNS FLOAT
BEGIN
DECLARE floatVal FLOAT;
DECLARE remainder FLOAT;
SET @sign = 1;
IF (startDate > endDate) THEN
SET @temp = startDate;
SET startDate = endDate;
SET endDate = @temp;
SET @sign = -1;
END IF;
SET floatVal = ROUND(
TIMESTAMPDIFF(MONTH, DATE_FORMAT(startDate, '%Y-%m-01'), DATE_FORMAT(endDate, '%Y-%m-01')) +
(DAY(endDate) / DAY(LAST_DAY(endDate))) -
(DAY(startDate) / DAY(LAST_DAY(startDate))) +
IF (MONTH(startDate) != MONTH(endDate) and MONTH(startDate) = 2, IF (leap_year(startDate), 0.02, 0.03) , 0),
2
);
SET remainder = ROUND(floatVal % 1, 2);
IF (remainder = 0) THEN
RETURN floatVal * @sign;
END IF;
/* error 0.02 rounding */
IF (remainder >= 0.5 and (1 - remainder) <= 0.02) THEN
SET floatVal = floatVal + (1 - remainder);
ELSEIF (remainder < 0.5 and remainder <= 0.02) THEN
SET floatVal = floatVal - remainder;
END IF;
RETURN floatVal * @sign;
END;
//
DELIMITER ;
SELECT
date_diff_in_months('2024-02-15', '2024-03-15'),#1
date_diff_in_months('2025-02-15', '2025-03-15'),#1
date_diff_in_months('2024-02-15', '2024-04-15'),#2
date_diff_in_months('2025-02-15', '2025-04-15'),#2
date_diff_in_months('2024-01-15', '2024-04-15'),#3
date_diff_in_months('2025-01-15', '2025-04-15'),#3
date_diff_in_months('2025-01-15', '2025-04-20'),#3.18
date_diff_in_months('2024-01-15', '2025-01-15'),#12
date_diff_in_months('2024-01-15', '2025-04-20'),#15.18
date_diff_in_months('2024-04-15', '2025-01-15'),#9
date_diff_in_months('2024-04-15', '2025-01-20'),#9.15
date_diff_in_months('2024-04-15', '2025-01-25'),#9.31
date_diff_in_months('2024-06-30', '2024-07-30'),#0.97
date_diff_in_months('2024-06-30', '2024-07-31'),#1
date_diff_in_months('2024-06-30', '2024-08-01'),#1.03
date_diff_in_months('2024-08-01', '2024-06-30')#-1.03
;