获取两个日期在两个日期之间的差异在几个月和几天在sql
我需要得到两个日期之间的差异说如果差异是84天,我应该可能有2个月和14天的输出,我只是代码给出总数。下面是代码获取两个日期在两个日期之间的差异在几个月和几天在sql
SELECT Months_between(To_date('20120325', 'YYYYMMDD'),
To_date('20120101', 'YYYYMMDD'))
num_months,
(To_date('20120325', 'YYYYMMDD') - To_date('20120101', 'YYYYMMDD'))
diff_in_days
FROM dual;
输出是:
NUM_MONTHS DIFF_IN_DAYS
2.774193548 84
我需要例如输出此查询是2个月,14天最坏的,否则我也不会介意,如果我能有几个月后的确切日期,因为那些日子不是真的14,因为所有的月份都没有30天。
select
dt1, dt2,
trunc(months_between(dt2,dt1)) mths,
dt2 - add_months(dt1, trunc(months_between(dt2,dt1))) days
from
(
select date '2012-01-01' dt1, date '2012-03-25' dt2 from dual union all
select date '2012-01-01' dt1, date '2013-01-01' dt2 from dual union all
select date '2012-01-01' dt1, date '2012-01-01' dt2 from dual union all
select date '2012-02-28' dt1, date '2012-03-01' dt2 from dual union all
select date '2013-02-28' dt1, date '2013-03-01' dt2 from dual union all
select date '2013-02-28' dt1, date '2013-04-01' dt2 from dual union all
select trunc(sysdate-1) dt1, sysdate from dual
) sample_data
个结果:
| DT1 | DT2 | MTHS | DAYS |
----------------------------------------------------------------------------
| January, 01 2012 00:00:00 | March, 25 2012 00:00:00 | 2 | 24 |
| January, 01 2012 00:00:00 | January, 01 2013 00:00:00 | 12 | 0 |
| January, 01 2012 00:00:00 | January, 01 2012 00:00:00 | 0 | 0 |
| February, 28 2012 00:00:00 | March, 01 2012 00:00:00 | 0 | 2 |
| February, 28 2013 00:00:00 | March, 01 2013 00:00:00 | 0 | 1 |
| February, 28 2013 00:00:00 | April, 01 2013 00:00:00 | 1 | 1 |
| August, 14 2013 00:00:00 | August, 15 2013 05:47:26 | 0 | 1.241273 |
链接到测试:SQLFiddle
请问dt2和dt1代表什么我认为我有些约会? – ErrorNotFoundException 2013-08-14 05:41:18
希望您不介意我向查询中添加了一些示例数据。没有其他答案能够产生准确的结果。大多数甚至不是很接近。这是2月28日左右的结果,真正显示出差异。假设每月30或31天不会总是有效。我不确定是否有用于计算月份和日期的官方算法,但这些结果对我来说是最好的。 – 2013-08-15 05:29:16
@Stanley我加入了'jonearles'并为闰年和日期添加了两个更多的例子,加上链接到任何人都可以在线测试解决方案的网站。 – ThinkJet 2013-08-15 06:07:28
MSSQL语法: DATEDIFF(日期部分,开始日期,结束日期)
甲骨文:这将返回天数
select
round(Second_date - First_date) as Diff_InDays,round ((Second_date - First_date)/(30),1) as Diff_InMonths,round ((Second_date - First_date) * (60*24),2) as TimeIn_Minitues
from
(
select
to_date('01/01/2012 01:30:00 PM','mm/dd/yyyy hh:mi:ss am') as First_date
,to_date('05/02/2012 01:35:00 PM','mm/dd/yyyy HH:MI:SS AM') as Second_date
from
dual
) result;
这是一个transact sql语法,而不是oracle – Oofpez 2012-07-16 07:53:57
即使在tsql中不会给OP要求 – Madhivanan 2012-07-16 07:54:37
上午在使用Oracle和Talend Open Studio – ErrorNotFoundException 2012-07-16 07:55:27
SELECT (MONTHS_BETWEEN(date2,date1) + (datediff(day,date2,date1))/30) as num_months,
datediff(day,date2,date1) as diff_in_days FROM dual;
// You should replace date2 with TO_DATE('2012/03/25', 'YYYY/MM/DD')
// You should replace date1 with TO_DATE('2012/01/01', 'YYYY/MM/DD')
// To get you results
DateDiff是在什么Oracle表中,因为它在双重>返回Invaid标识符? – ErrorNotFoundException 2012-07-16 10:46:47
是的。你是对的我会尽快为你提供oracle的具体解决方案 – Sami 2012-07-16 11:49:22
如果datediff不适合你只是简单地尝试date2-date1而不是datediff(day,date2,date1) 无论工作与我分享请谢谢 – Sami 2012-07-16 12:28:20
见下面的查询(假定@ DT1> = @ DT2);
Declare @dt1 datetime = '2013-7-3'
Declare @dt2 datetime = '2013-5-2'
select abs(DATEDIFF(DD, @dt2, @dt1)) Days,
case when @dt1 >= @dt2
then case when DAY(@dt2)<=DAY(@dt1)
then Convert(varchar, DATEDIFF(MONTH, @dt2, @dt1)) + CONVERT(varchar, ' Month(s) ') + Convert(varchar, DAY(@dt1)-DAY(@dt2)) + CONVERT(varchar, 'Day(s).')
else Convert(varchar, DATEDIFF(MONTH, @dt2, @dt1)-1) + CONVERT(varchar, ' Month(s) ') + convert(varchar, abs(DATEDIFF(DD, @dt1, DateAdd(Month, -1, @dt1))) - (DAY(@dt2)-DAY(@dt1))) + CONVERT(varchar, 'Day(s).')
end
else 'See asumption: @dt1 must be >= @dt2'
end In_Months_Days
返回:
Days | In_Months_Days
62 | 2 Month(s) 1Day(s).
Oracle的问题,而不是一个SQL Server的问题。 – 2013-08-13 21:27:30
更新的正确性。最初由@jen回答。
with DATES as (
select TO_DATE('20120101', 'YYYYMMDD') as Date1,
TO_DATE('20120325', 'YYYYMMDD') as Date2
from DUAL union all
select TO_DATE('20120101', 'YYYYMMDD') as Date1,
TO_DATE('20130101', 'YYYYMMDD') as Date2
from DUAL union all
select TO_DATE('20120101', 'YYYYMMDD') as Date1,
TO_DATE('20120101', 'YYYYMMDD') as Date2
from DUAL union all
select TO_DATE('20130228', 'YYYYMMDD') as Date1,
TO_DATE('20130301', 'YYYYMMDD') as Date2
from DUAL union all
select TO_DATE('20130228', 'YYYYMMDD') as Date1,
TO_DATE('20130401', 'YYYYMMDD') as Date2
from DUAL
), MONTHS_BTW as (
select Date1, Date2,
MONTHS_BETWEEN(Date2, Date1) as NumOfMonths
from DATES
)
select TO_CHAR(Date1, 'MON DD YYYY') as Date_1,
TO_CHAR(Date2, 'MON DD YYYY') as Date_2,
NumOfMonths as Num_Of_Months,
TRUNC(NumOfMonths) as "Month(s)",
ADD_MONTHS(Date2, - TRUNC(NumOfMonths)) - Date1 as "Day(s)"
from MONTHS_BTW;
SQLFiddle演示:
+--------------+--------------+-----------------+-----------+--------+ | DATE_1 | DATE_2 | NUM_OF_MONTHS | MONTH(S) | DAY(S) | +--------------+--------------+-----------------+-----------+--------+ | JAN 01 2012 | MAR 25 2012 | 2.774193548387 | 2 | 24 | | JAN 01 2012 | JAN 01 2013 | 12 | 12 | 0 | | JAN 01 2012 | JAN 01 2012 | 0 | 0 | 0 | | FEB 28 2013 | MAR 01 2013 | 0.129032258065 | 0 | 1 | | FEB 28 2013 | APR 01 2013 | 1.129032258065 | 1 | 1 | +--------------+--------------+-----------------+-----------+--------+
注意,如何在过去的两个日期,Oracle报表月份的小数部分(这使天)不正确。 0.1290
恰好对应于4
天,甲骨文考虑在一个月内(3月和4月)考虑31
天。
我后一个月就会考虑30天
select CONCAT (CONCAT (num_months,' MONTHS '), CONCAT ((days-(num_months)*30),' DAYS '))
from (
SELECT floor(Months_between(To_date('20120325', 'YYYYMMDD'),
To_date('20120101', 'YYYYMMDD')))
num_months,
(To_date('20120325', 'YYYYMMDD') - To_date('20120101', 'YYYYMMDD'))
days
FROM dual);
的解决方案是这是你所换货?
select trunc(months_between(To_date('20120325', 'YYYYMMDD'),to_date('20120101','YYYYMMDD'))) months,
round(To_date('20120325', 'YYYYMMDD')-add_months(to_date('20120101','YYYYMMDD'),
trunc(months_between(To_date('20120325', 'YYYYMMDD'),to_date('20120101','YYYYMMDD'))))) days
from dual;
如20120129 - 20120325这样的日期将不起作用。 – Noel 2013-08-15 05:03:34
谢谢,现在是:) – planben 2013-08-15 05:23:56
这也是正确的:P – ErrorNotFoundException 2013-08-15 08:52:42
我认为这是没有定义你的问题不够好,原因如下。
依靠months_between的答案必须处理以下问题:函数报告2013-02-28和2013-03-31之间以及2013-01-28和2013-02-28之间的一个月,以及2013-01-31和2013-02-28之间(我怀疑有些回答者在实践中没有使用这些功能,或者现在要去检查一些生产代码!)
这是有记录的行为,其中分别是各自月份的最后一个日期或落在当月的同一天的日期被判断为相隔几个月的整数。
因此,比较2013-02-28与2013-01-28或2013-01-31时得到的结果是“1”,但与2013-01-29或2013-01- 30分别给出了0.967741935484和0.935483870968 - 因此当一个日期接近另一个时,由该函数报告的差异可以增加。
如果这不是一个可接受的情况,那么你将不得不写一个更复杂的函数,或者只是依靠一个假设每月30(例如)天的计算。在后一种情况下,你将如何处理2013-02-28和2013-03-31?
您提出了一些优秀的观点。这是一个没有完美答案的简单常见问题。无论使用哪种解决方案,都应该包含免责声明。我仍然会把赏金奖给公认的答案,因为它对我来说很合适。但那可能只是因为我太多地使用了'months_between'。 – 2013-08-16 19:21:34
是的,正如Jon Heller所说的,2-28到3-31是'1'而不是2-28到3-28 ='1'的好处。这就是为什么当你想到几天的时候,你应该真正数天,而不是“MONTHS_BETWEEN”。 – vapcguy 2016-12-06 14:49:58
找出年 - 在ORALE的Sql月 - 日两天之间
select
trunc(trunc(months_between(To_date('20120101', 'YYYYMMDD'),to_date('19910228','YYYYMMDD')))/12) years ,
trunc(months_between(To_date('20120101', 'YYYYMMDD'),to_date('19910228','YYYYMMDD')))
-
(trunc(trunc(months_between(To_date('20120101', 'YYYYMMDD'),to_date('19910228','YYYYMMDD')))/12))*12
months,
round(To_date('20120101', 'YYYYMMDD')-add_months(to_date('19910228','YYYYMMDD'),
trunc(months_between(To_date('20120101', 'YYYYMMDD'),to_date('19910228','YYYYMMDD'))))) days
from dual;
在这里,我只是在做今天的区别,并在表中的CREATED_DATE
DATE
场,这显然是在过去的某个日期:
SELECT
((FLOOR(ABS(MONTHS_BETWEEN(CREATED_DATE, SYSDATE)))/12) * 12) || ' months, ' AS MONTHS,
-- we take total days - years(as days) - months(as days) to get remaining days
FLOOR((SYSDATE - CREATED_DATE) - -- total days
(FLOOR((SYSDATE - CREATED_DATE)/365)*12)*(365/12) - -- years, as days
-- this is total months - years (as months), to get number of months,
-- then multiplied by 30.416667 to get months as days (and remove it from total days)
FLOOR(((SYSDATE - CREATED_DATE)/365)*12 - (FLOOR((SYSDATE - CREATED_DATE)/365)*12)) * (365/12))
|| ' days ' AS DAYS
FROM MyTable
我使用(一十二分之三百六十五),或30.416667,我的换算系数,因为我使用的总天数和删除年和月(如昼s)来获得剩余天数。无论如何,这对我的目的来说已经足够了。
是否没有人回答这个问题? – ErrorNotFoundException 2012-11-01 10:07:08
不应该是2个月和24天吗? – Noel 2013-08-14 00:38:07