programing

두 날짜 간의 일/월/년(일자) 차이를 구하는 방법은 무엇입니까?

yellowcard 2023. 4. 20. 20:45
반응형

두 날짜 간의 일/월/년(일자) 차이를 구하는 방법은 무엇입니까?

Postgre에서 SQL Server 기능을 구현하는 방법을 찾고 있습니다.SQL. 즉, 이 함수는 지정된 시작 날짜와 종료 날짜 사이에 교차된 지정된 날짜 부분 경계의 개수(부호 있는 정수 값)를 반환합니다.

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 ('2015-01-12'::date - '2015-01-01'::date) AS days;

그 결과:

 days
------
   11
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

자세한 날짜 정보입니다.

최선의 답을 찾는 데 시간을 들였고, 이제 알 것 같아요.

이 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'));

..날짜 문자열의 각 부분 간에 문자 그대로 차이가 나는 것이지, 두 날짜 사이의 시간이 아닙니다.

I.E:

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'와 '2012-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 Server 함수를 실행할 때와 동일한 결과를 얻으려고 합니다. DATEDIFF ( datepart , startdate , enddate )어디에datepart걸린다dd,mm, 또는yy.

이 함수는 다음과 같이 정의됩니다.

이 함수는 지정된 시작 날짜와 종료 날짜 사이에 교차된 지정된 날짜 부분 경계 카운트를(부호 있는 정수 값으로) 반환합니다.

즉, 일 경계, 월 경계 또는 년 경계를 교차하는 수를 의미합니다.몇 일, 몇 달, 몇 년의 기간이 아니라그래서...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

Riki_tiki_tavi의 답변을 확대해서 데이터를 얻고 싶습니다.SQL Server의 거의 모든 작업을 수행하는 Dateiff 함수를 만들었습니다.그러면 어떤 단위든 고려할 수 있습니다.

create function datediff(units character varying, start_t timestamp without time zone, end_t timestamp without time zone) returns integer
language plpgsql
 as
 $$
DECLARE
 diff_interval INTERVAL; 
 diff INT = 0;
 years_diff INT = 0;
BEGIN
 IF units IN ('yy', 'yyyy', 'year', 'mm', 'm', 'month') THEN
   years_diff = DATE_PART('year', end_t) - DATE_PART('year', start_t);

   IF units IN ('yy', 'yyyy', 'year') THEN
     -- SQL Server does not count full years passed (only difference between year parts)
     RETURN years_diff;
   ELSE
     -- If end month is less than start month it will subtracted
     RETURN years_diff * 12 + (DATE_PART('month', end_t) - DATE_PART('month', start_t)); 
   END IF;
 END IF;

 -- Minus operator returns interval 'DDD days HH:MI:SS'  
 diff_interval = end_t - start_t;

 diff = diff + DATE_PART('day', diff_interval);

 IF units IN ('wk', 'ww', 'week') THEN
   diff = diff/7;
   RETURN diff;
 END IF;

 IF units IN ('dd', 'd', 'day') THEN
   RETURN diff;
 END IF;

 diff = diff * 24 + DATE_PART('hour', diff_interval); 

 IF units IN ('hh', 'hour') THEN
    RETURN diff;
 END IF;

 diff = diff * 60 + DATE_PART('minute', diff_interval);

 IF units IN ('mi', 'n', 'minute') THEN
    RETURN diff;
 END IF;

 diff = diff * 60 + DATE_PART('second', diff_interval);

 RETURN diff;
END;
$$;

출력의 완전한 예를 다음에 나타냅니다.psql (10.1, 서버 9.5.10)

30보다 58이 .
age에서 언급한합니다.

drop table t;
create table t(
    d1 date
);

insert into t values(current_date - interval '58 day');

select d1
, current_timestamp - d1::timestamp date_diff
, date_part('day', current_timestamp - d1::timestamp)
from t;

     d1     |        date_diff        | date_part
------------+-------------------------+-----------
 2018-05-21 | 58 days 21:41:07.992731 |        58

또 하나의 솔루션, '년'의 차이를 나타내는 버전:

SELECT count(*) - 1 FROM (SELECT distinct(date_trunc('year', generate_series('2010-04-01'::timestamp, '2012-03-05', '1 week')))) x

    2

(1열)

그리고 몇 달 동안 같은 수법을 썼죠

SELECT count(*) - 1 FROM (SELECT distinct(date_trunc('month', generate_series('2010-04-01'::timestamp, '2012-03-05', '1 week')))) x

   23

(1열)

실제 쿼리에는 generate_series 대신 시간/일/주/주별로 그룹화된 타임스탬프 시퀀스가 있을 수 있습니다.

★★★★★★★★★★★★★★★★★.'count(distinct(date_trunc('month', ts)))'왼쪽에서 '왼쪽'을 선택하면 '왼쪽'으로 하면 됩니다.

SELECT sum(a - b)/count(distinct(date_trunc('month', c))) FROM d

여기서 generate_series()를 사용한 것은 간결함뿐입니다.

언급URL : https://stackoverflow.com/questions/17833176/how-to-get-difference-of-days-months-years-datediff-between-two-dates

반응형