programing

두 날짜 사이의 차이(월 단위 및 일 단위)를 sql로 가져옵니다.

javamemo 2023. 7. 29. 08:04
반응형

두 날짜 사이의 차이(월 단위 및 일 단위)를 sql로 가져옵니다.

나는 두 날짜의 차이를 알아야 합니다. 만약 차이가 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일이어야 합니다. 그렇지 않으면 모든 달에는 30일이 없기 때문에 해당 날짜가 실제로 14일이 아니기 때문에 해당 월 이후에 정확한 날짜를 지정할 수 있는지 여부는 신경 쓰지 않습니다.

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 |

테스트 링크: SQLFidle

정확성을 위해 업데이트되었습니다.원래는 @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;

SQL 중간 데모:

+--------------+--------------+-----------------+-----------+--------+DATE_1 | DATE_2 | NUM_OF_MONTS | 월(S) | 일(S) |+--------------+--------------+-----------------+-----------+--------+2012년 1월 1일 | 2012년 3월 25일 | 2.774193548387 | 2 | 24 |2012년 1월 1일 | 2013년 1월 1일 | 12 | 12 | 0 |2012년 1월 1일 | 2012년 1월 1일 | 0 | 0 | 0 | 0 |2월 28일2013 | 2013년 3월 01일 | 0.129032258065 | 0 | 1 |2013년 2월 28일 | 2013년 4월 01일 | 1.129032258065 | 1 | 1 |+--------------+--------------+-----------------+-----------+--------+

마지막 두 날짜에 대해 Oracle은 월(일)의 소수 부분을 잘못 보고합니다.0.1290는 정히일니다합치에 합니다.4하는 Oracle과 31한 달의 일(3월과 4월 모두)

저는 당신의 질문이 다음과 같은 이유로 충분히 정의되지 않았다고 생각합니다.

month_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을 어떻게 처리하시겠습니까?

이게 당신이 말한 것입니까?

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;

여기서 난 그저 오늘과 다른 것을 하고 있을 뿐이고,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을 변환 계수로 사용합니다. 이는 총 일수를 사용하고 남은 일수를 얻기 위해 년 및 월(일)을 제거하기 때문입니다.어쨌든 제 목적에는 충분했습니다.

제가 게시하는 솔루션은 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);

Orale Sql에서 년 - 월 - 일 2일 간 확인


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

아래 쿼리를 참조하십시오(예: @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).

언급URL : https://stackoverflow.com/questions/11500098/get-the-difference-between-two-dates-both-in-months-and-days-in-sql

반응형