2つの日付の差を取得する必要があります。差が84日であれば、おそらく2ヶ月と14日として出力する必要があります。私が持っているコードは合計を示しています。ここにコードがあります
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
正確さのために更新されました。元は@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)| + -------------- + -------------- + --------- -------- + ----------- + -------- + | 2012年1月1日| 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 | + -------------- + -------------- + ------ ----------- + ----------- + -------- +
最後の2つの日付について、Oracleは月の小数部分(日を与える)を誤って報告することに注意してください。 0.1290
は、正確に4
日に対応します。Oracleでは、1か月の31
日(3月と4月の両方)を考慮します。
次の理由から、あなたの質問は十分に定義されていないと思います。
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にどのように対処しますか?
ここでは、今日と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
合計日数を使用し、年と月(日)を削除して残りの日数を取得するため、(365/12)または30.416667を変換係数として使用します。とにかく、私の目的には十分でした。
これはあなたが言及したことですか?
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;
私が投稿したソリューションは、30日間で1か月を検討します
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);