두 날짜 간의 일/월/년(일자) 차이를 구하는 방법은 무엇입니까?
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
'programing' 카테고리의 다른 글
최소 날짜(1753년 1월 1일)를 반환하는 SQL Server 함수 (0) | 2023.04.20 |
---|---|
섬네일 이미지 생성 (0) | 2023.04.20 |
왜 String을 사용합니까?== 이상입니까? (0) | 2023.04.20 |
'마이크로소프트'ACE.OLEDB.12.0' 공급자가 로컬 시스템에 등록되어 있지 않습니다. (0) | 2023.04.20 |
역할 관리자 기능이 활성화되지 않았습니다. (0) | 2023.04.20 |