2012-07-16 84 views
13

我需要得到兩個日期之間的差異說如果差異是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天。

+0

是否沒有人回答這個問題? – ErrorNotFoundException 2012-11-01 10:07:08

+2

不應該是2個月和24天嗎? – Noel 2013-08-14 00:38:07

回答

17
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

+0

請問dt2和dt1代表什麼我認爲我有些約會? – ErrorNotFoundException 2013-08-14 05:41:18

+1

希望您不介意我向查詢中添加了一些示例數據。沒有其他答案能夠產生準確的結果。大多數甚至不是很接近。這是2月28日左右的結果,真正顯示出差異。假設每月30或31天不會總是有效。我不確定是否有用於計算月份和日期的官方算法,但這些結果對我來說是最好的。 – 2013-08-15 05:29:16

+0

@Stanley我加入了'jonearles'併爲閏年和日期添加了兩個更多的例子,加上鍊接到任何人都可以在線測試解決方案的網站。 – ThinkJet 2013-08-15 06:07:28

-2

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; 

演示:http://sqlfiddle.com/#!4/c26e8/36

+0

這是一個transact sql語法,而不是oracle – Oofpez 2012-07-16 07:53:57

+0

即使在tsql中不會給OP要求 – Madhivanan 2012-07-16 07:54:37

+0

上午在使用Oracle和Talend Open Studio – ErrorNotFoundException 2012-07-16 07:55:27

-2
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 
+0

DateDiff是在什麼Oracle表中,因爲它在雙重>返回Invaid標識符? – ErrorNotFoundException 2012-07-16 10:46:47

+0

是的。你是對的我會盡快爲你提供oracle的具體解決方案 – Sami 2012-07-16 11:49:22

+0

如果datediff不適合你只是簡單地嘗試date2-date1而不是datediff(day,date2,date1) 無論工作與我分享請謝謝 – Sami 2012-07-16 12:28:20

-4

見下面的查詢(假定@ 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). 
+1

Oracle的問題,而不是一個SQL Server的問題。 – 2013-08-13 21:27:30

2

更新的正確性。最初由@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天。

+0

不是很準確。它應該已經返回了24天。 – Noel 2013-08-14 11:32:46

+0

@ Ramblin'Man感謝您的高擡頭。顯然,使用31作爲「一個月內的日子」似乎已經修復了它。我實際上認爲30和31有時候會返回確切的時間,有時候會關閉1天(取決於選擇幾個月),但是,這一輪會照顧它。如果你喜歡,再看看。 – 2013-08-14 12:53:43

+2

乘以30或31並不是一個好主意。它會在某些日期中斷,尤其是在涉及二月的時候。 – Noel 2013-08-15 05:32:11

0

我後一個月就會考慮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); 
+3

乘以30或31並不是一個好主意。它會在某些日期中斷,尤其是在涉及二月的時候。 – Noel 2013-08-15 05:32:51

+0

我乘以'(365/12)'或'30.41667',但使用的方式不是直接找到使用該結果數字的實際日期,如上所述。您可以使用它來將MONTHS_BETWEEN'轉換爲天數,從而得出總天數,然後減去數月的時間(以天爲單位),以查找實際的剩餘天數。 – vapcguy 2016-12-06 15:32:16

1

的解決方案是這是你所換貨?

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; 
+0

如20120129 - 20120325這樣的日期將不起作用。 – Noel 2013-08-15 05:03:34

+0

謝謝,現在是:) – planben 2013-08-15 05:23:56

+0

這也是正確的:P – ErrorNotFoundException 2013-08-15 08:52:42

2

我認爲這是沒有定義你的問題不夠好,原因如下。

依靠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?

+1

您提出了一些優秀的觀點。這是一個沒有完美答案的簡單常見問題。無論使用哪種解決方案,都應該包含免責聲明。我仍然會把賞金獎給公認的答案,因爲它對我來說很合適。但那可能只是因爲我太多地使用了'months_between'。 – 2013-08-16 19:21:34

+0

是的,正如Jon Heller所說的,2-28到3-31是'1'而不是2-28到3-28 ='1'的好處。這就是爲什麼當你想到幾天的時候,你應該真正數天,而不是「MONTHS_BETWEEN」。 – vapcguy 2016-12-06 14:49:58

-2

找出年 - 在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; 
1

在這裏,我只是在做今天的區別,並在表中的CREATED_DATEDATE場,這顯然是在過去的某個日期:

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)來獲得剩餘天數。無論如何,這對我的目的來說已經足夠了。

相關問題