[postgresql] PostgreSQL : 두 날짜 사이의 일 / 월 / 년

PostgreSQL에서 SQLServer 기능 datediff 를 구현하는 방법을 찾고 있습니다. 그건,

이 함수는 지정된 startdate와 enddate 사이에 교차하는 지정된 datepart 경계의 개수 (부호있는 정수 값)를 반환합니다.

datediff(dd, '2010-04-01', '2012-03-05') = 704 // 704 changes of day in this interval
datediff(mm, '2010-04-01', '2012-03-05') = 23  // 23 changes of month
datediff(yy, '2010-04-01', '2012-03-05') = 2   // 2 changes of year

단순히 빼기를 사용하여 ‘dd’를 할 수 있다는 것을 알고 있지만 다른 두 가지에 대해서는 어떤 생각이 있습니까?



답변

SELECT
  AGE('2012-03-05', '2010-04-01'),
  DATE_PART('year', AGE('2012-03-05', '2010-04-01')) AS years,
  DATE_PART('month', AGE('2012-03-05', '2010-04-01')) AS months,
  DATE_PART('day', AGE('2012-03-05', '2010-04-01')) AS days;

이렇게하면 두 날짜 사이에 전체 년, 월, 일 이 제공됩니다 .

          age          | years | months | days
-----------------------+-------+--------+------
 1 year 11 mons 4 days |     1 |     11 |    4

더 자세한 datediff 정보 .


답변

간단히 빼기 :

SELECT ('2015-01-12'::date - '2015-01-01'::date) AS days;

결과:

 days
------
   11


답변

나는 최선의 답을 찾기 위해 시간을 보냈고 나는 그것을 가지고 있다고 생각한다.

이 SQL은 두 날짜 사이의 일 수를 integer다음 과 같이 제공합니다 .

SELECT
    (EXTRACT(epoch from age('2017-6-15', now())) / 86400)::int

.. 오늘 ( 2017-3-28) 실행하면 다음을 제공합니다.

?column?
------------
77

받아 들여진 대답에 대한 오해 :

select age('2010-04-01', '2012-03-05'),
   date_part('year',age('2010-04-01', '2012-03-05')),
   date_part('month',age('2010-04-01', '2012-03-05')),
   date_part('day',age('2010-04-01', '2012-03-05'));

.. 두 날짜 사이의 시간이 아니라 날짜 문자열 부분 사이의 문자적인 차이를 얻을 수 있다는 것입니다.

IE :

Age(interval)=-1 years -11 mons -4 days;

Years(double precision)=-1;

Months(double precision)=-11;

Days(double precision)=-4;


답변

필요한 것과 거의 동일한 기능 (atiruz의 답변, 여기 에서 UDF의 축약 버전 )

CREATE OR REPLACE FUNCTION datediff(type VARCHAR, date_from DATE, date_to DATE) RETURNS INTEGER LANGUAGE plpgsql
AS
$$
DECLARE age INTERVAL;
BEGIN
    CASE type
        WHEN 'year' THEN
            RETURN date_part('year', date_to) - date_part('year', date_from);
        WHEN 'month' THEN
            age := age(date_to, date_from);
            RETURN date_part('year', age) * 12 + date_part('month', age);
        ELSE
            RETURN (date_to - date_from)::int;
    END CASE;
END;
$$;

용법:

/* Get months count between two dates */
SELECT datediff('month', '2015-02-14'::date, '2016-01-03'::date);
/* Result: 10 */

/* Get years count between two dates */
SELECT datediff('year', '2015-02-14'::date, '2016-01-03'::date);
/* Result: 1 */

/* Get days count between two dates */
SELECT datediff('day', '2015-02-14'::date, '2016-01-03'::date);
/* Result: 323 */

/* Get months count between specified and current date */
SELECT datediff('month', '2015-02-14'::date, NOW()::date);
/* Result: 47 */


답변

SELECT date_part ('year', f) * 12
     + date_part ('month', f)
FROM age ('2015-06-12'::DATE, '2014-12-01'::DATE) f

결과 : 6


답변

@WebWanderer의 답변은 SQL 서버를 사용하는 DateDiff에 매우 가깝지만 정확하지 않습니다. 이는 age () 함수의 사용 때문입니다.

예를 들어 ‘2019-07-29’와 ‘2020-06-25’사이의 날은 332를 반환해야하지만 age () 함수를 사용하면 327을 반환합니다. age ()는 ’10 mons 27 days ‘를 반환하고 매월 30 일로 정확하지 않습니다.

정확한 결과를 얻으려면 타임 스탬프를 사용하십시오. 예

ceil((select extract(epoch from (current_date::timestamp - <your_date>::timestamp)) / 86400))


답변

이 질문은 오해로 가득 차 있습니다. 먼저 질문을 완전히 이해하겠습니다. 아스 커는 실행할 때와 동일한 결과를 얻을 싶어 MS SQL 서버 기능을 한다 , 또는를 .DATEDIFF ( datepart , startdate , enddate )datepartddmmyy

이 함수는 다음에 의해 정의됩니다.

이 함수는 지정된 startdate와 enddate 사이에 교차하는 지정된 datepart 경계의 개수 (부호있는 정수 값)를 반환합니다.

이는 얼마나 많은 일 경계, 월 경계 또는 연도 경계가 교차되는지를 의미합니다. 몇 일, 몇 달 또는 몇 년 사이가 아닙니다. 그렇기 때문에 datediff(yy, '2010-04-01', '2012-03-05')1이 아니라 2가됩니다.이 날짜 사이에는 2 년 미만이 있습니다. 즉, 전체 1 년이 지났지 만 2010 년부터 2011 년까지, 2011 년부터 2012 년까지 2 년의 경계를 넘었습니다.

다음은 논리를 올바르게 복제하기위한 최선의 시도입니다.

-- datediff(dd`, '2010-04-01', '2012-03-05') = 704 // 704 changes of day in this interval
select ('2012-03-05'::date - '2010-04-01'::date );
-- 704 changes of day

-- datediff(mm, '2010-04-01', '2012-03-05') = 23  // 23 changes of month
select (date_part('year', '2012-03-05'::date) - date_part('year', '2010-04-01'::date)) * 12 + date_part('month', '2012-03-05'::date) - date_part('month', '2010-04-01'::date)
-- 23 changes of month

-- datediff(yy, '2010-04-01', '2012-03-05') = 2   // 2 changes of year
select date_part('year', '2012-03-05'::date) - date_part('year', '2010-04-01'::date);
-- 2 changes of year