MySQL의 날짜 사이의 달의 차이
-
08-07-2019 - |
문제
2 개의 날짜 시간 필드 사이의 달 수를 계산하려고합니다.
Unix 타임 스탬프를 얻는 것보다 더 좋은 방법이 있습니까?
해결책
그만큼 데이트 디프 기능은 두 날짜 사이의 일을 줄 수 있습니다. 한 달을 어떻게 정의합니까? (28, 29, 30 또는 31 일?)
다른 팁
주어진 두 날짜 사이의 월 차분 :
아직 언급되지 않은 것에 놀랐습니다.
살펴보십시오 timestampDiff () MySQL에서 기능.
이것이 당신이 할 수있는 일은 두 가지를 통과하는 것입니다. TIMESTAMP
또는 DATETIME
값 (또는 심지어 DATE
MySQL이 자동으로 컨버터 될 것입니다)와 차이를 기반으로하려는 시간 단위.
지정할 수 있습니다 MONTH
첫 번째 매개 변수의 단위로 :
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-04')
-- Outputs: 0
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-05')
-- Outputs: 1
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-15')
-- Outputs: 1
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-12-16')
-- Outputs: 7
기본적으로 매개 변수 목록의 첫 번째 날짜에서 경과 한 개월 수를 얻습니다. 이 솔루션은 매월 다양한 일 (28,30,31)을 자동으로 보상 할뿐만 아니라 도약 연도를 고려하여 해당 사항에 대해 걱정할 필요가 없습니다.
정밀한 월 차분 :
경과 한 달에 소수점 정밀도를 소개하려면 조금 더 복잡하지만 다음과 같은 방법은 다음과 같습니다.
SELECT
TIMESTAMPDIFF(MONTH, startdate, enddate) +
DATEDIFF(
enddate,
startdate + INTERVAL
TIMESTAMPDIFF(MONTH, startdate, enddate)
MONTH
) /
DATEDIFF(
startdate + INTERVAL
TIMESTAMPDIFF(MONTH, startdate, enddate) + 1
MONTH,
startdate + INTERVAL
TIMESTAMPDIFF(MONTH, startdate, enddate)
MONTH
)
어디에 startdate
그리고 enddate
테이블의 두 날짜 열 또는 스크립트의 입력 매개 변수로 날짜 매개 변수입니까?
예 :
With startdate = '2012-05-05' AND enddate = '2012-05-27':
-- Outputs: 0.7097
With startdate = '2012-05-05' AND enddate = '2012-06-13':
-- Outputs: 1.2667
With startdate = '2012-02-27' AND enddate = '2012-06-02':
-- Outputs: 3.1935
period_diff 두 날짜 사이의 달을 계산합니다.
예를 들어, now ()과 your_table의 시간 열의 차이를 계산합니다.
select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;
EvryOne은 언뜻보기에 그것을 명확하게 이해할 것이기 때문에 이런 식으로 선호합니다.
SELECT
12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months
FROM
tab;
여기에 많은 답변이 표시되는 것처럼 '올바른'대답은 정확히 필요한 것에 달려 있습니다. 제 경우에는 필요합니다 가장 가까운 숫자로 반올림합니다.
1 월 1 일 -1 월 31 일 : 0 개월, 거의 1 개월 길이입니다. 1 월 1 일 -2 월 1 일? 한 달 내내 1 개월, 정확히 1 개월입니다.
수를 얻으려면 전체 (완료) 달, 사용 :
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-01-31'); => 0
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-01'); => 1
얻기 위해 둥글게 몇 달 만에 다음을 사용할 수 있습니다.
SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1
SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1
이것은 +/- 5 일에 정확하며 범위는 1000 년 이상입니다. Zane의 대답은 분명히 더 정확하지만 내 취향에는 너무 장점입니다.
MySQL 매뉴얼에서 :
period_diff (p1, p2)
기간 P1과 P2 사이의 개월 수를 반환합니다. P1 및 P2는 Yymm 또는 Yyyymm 형식이어야합니다. 기간 인수 P1 및 P2는 날짜 값이 아닙니다.
MySQL> SELECT Period_Diff (200802,200703); -> 11
따라서 다음과 같은 일을 할 수 있습니다.
Select period_diff(concat(year(d1),if(month(d1)<10,'0',''),month(d1)), concat(year(d2),if(month(d2)<10,'0',''),month(d2))) as months from your_table;
여기서 D1과 D2가 날짜 표현식입니다.
나는 몇 달이 2가 아닌 02와 같은 두 자리 숫자인지 확인하기 위해 if () 문을 사용해야했습니다.
더 좋은 방법이 있습니까? 네. MySQL 타임 스탬프를 사용하지 마십시오. 그들이 36 바이트를 차지한다는 사실과는 별도로, 그들은 전혀 편리하지 않습니다. 나는 모든 날짜/시간 값에 대해 줄리안 날짜와 자정부터 몇 초를 사용하여 추천합니다. 이들은 결합하여 비 닉스 듀티를 형성 할 수 있습니다. 이것이 dword (서명되지 않은 4 바이트 정수)에 저장되면 EPOC 이후 2106까지의 날짜는 01/01/1970 max val = 4,294,967,295 - DWORD는 136 초의 136 년을 보유 할 수 있습니다.
Julian Dates는 날짜 계산을 할 때 작업하기에 매우 좋습니다. 비 닉스 시간 값은 날짜/시간 계산을 만들 때 작업하기에 좋습니다. 함께하지만 나는 장간 징후를 원합니다.
줄리안으로 전환하는 것은 좋은 언어로 매우 빨리 이루어질 수 있습니다. 포인터를 사용하여 약 900 CLK로 줄어 듭니다 (이것은 또한 문자열에서 정수로 변환하는 것입니다)
예를 들어 금융 시장과 같은 날짜/시간 정보를 사용하는 심각한 응용 프로그램에 들어가면 Julian Dates는 사실입니다.
쿼리는 다음과 같습니다.
select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where..
고객 레코드에서 생성 된 Datestamp 이후 여러 달의 달을 제공하여 MySQL이 내부적으로 달을 선택할 수 있도록합니다.
DROP FUNCTION IF EXISTS `calcula_edad` $$
CREATE DEFINER=`root`@`localhost` FUNCTION `calcula_edad`(pFecha1 date, pFecha2 date, pTipo char(1)) RETURNS int(11)
Begin
Declare vMeses int;
Declare vEdad int;
Set vMeses = period_diff( date_format( pFecha1, '%Y%m' ), date_format( pFecha2, '%Y%m' ) ) ;
/* Si el dia de la fecha1 es menor al dia de fecha2, restar 1 mes */
if day(pFecha1) < day(pFecha2) then
Set vMeses = VMeses - 1;
end if;
if pTipo='A' then
Set vEdad = vMeses div 12 ;
else
Set vEdad = vMeses ;
end if ;
Return vEdad;
End
select calcula_edad(curdate(),born_date,'M') -- for number of months between 2 dates
이 코드를 실행하면 날짜 형식 YYYY-MM-DD의 차이를 제공하는 함수 날짜가 생성됩니다.
DELIMITER $$
CREATE FUNCTION datedifference(date1 DATE, date2 DATE) RETURNS DATE
NO SQL
BEGIN
DECLARE dif DATE;
IF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < 0 THEN
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(DATE_SUB(date1, INTERVAL 1 MONTH)), '-', DAY(date2))))),
'%Y-%m-%d');
ELSEIF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < DAY(LAST_DAY(DATE_SUB(date1, INTERVAL 1 MONTH))) THEN
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))),
'%Y-%m-%d');
ELSE
SET dif=DATE_FORMAT(
CONCAT(
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 ,
'-',
PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 ,
'-',
DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))),
'%Y-%m-%d');
END IF;
RETURN dif;
END $$
DELIMITER;
이것은 몇 달의 정의를 원하는 방식에 따라 다릅니다. 이 질문에 대답하십시오. 이는 명확한 컷 #의 날로 정의됩니까?
며칠 동안 계산:
2 월 15 일 -> 29 (도약 연도) = 2008 년 3 월 1 일 + 365 = 2009 년 3 월 1 일. 3 월 1 일 -3 월 12 일 = 12 일. 14 + 365 + 12 = 391 일. 총 = 391 일 / (월의 AVG 일 = 30) = 13.03333
달의 계산:
2008 년 2 월 15 일 -209 년 2 월 15 일 = 12 월 15 일 -> 3 월 12 일 = 1 개월 미만 총 = 12 개월 또는 2 월 15 일 -3 월 12 일이 '지난 달'으로 간주되는 경우 13
SELECT *
FROM emp_salaryrevise_view
WHERE curr_year Between '2008' AND '2009'
AND MNTH Between '12' AND '1'
정밀도로 월 차분이 필요했습니다. Zane Bien의 솔루션은 올바른 방향에 있지만 그의 두 번째 및 세 번째 예는 부정확 한 결과를 제공합니다. 2 월의 날은 2 월의 일 수로 나눈 일은 5 월의 날과 5 월의 일 수로 나뉘어져 있지 않습니다. 따라서 두 번째 예제는 ((31-5 + 1)/31 + 13/30 =) 1.3043과 세 번째 예제 ((29-27 + 1)/29 + 2/30 + 3 =) 3.1701을 출력해야합니다.
다음 쿼리로 끝났습니다.
SELECT
'2012-02-27' AS startdate,
'2012-06-02' AS enddate,
TIMESTAMPDIFF(DAY, (SELECT startdate), (SELECT enddate)) AS days,
IF(MONTH((SELECT startdate)) = MONTH((SELECT enddate)), 0, (TIMESTAMPDIFF(DAY, (SELECT startdate), LAST_DAY((SELECT startdate)) + INTERVAL 1 DAY)) / DAY(LAST_DAY((SELECT startdate)))) AS period1,
TIMESTAMPDIFF(MONTH, LAST_DAY((SELECT startdate)) + INTERVAL 1 DAY, LAST_DAY((SELECT enddate))) AS period2,
IF(MONTH((SELECT startdate)) = MONTH((SELECT enddate)), (SELECT days), DAY((SELECT enddate))) / DAY(LAST_DAY((SELECT enddate))) AS period3,
(SELECT period1) + (SELECT period2) + (SELECT period3) AS months
이런 식으로 몇 년, 몇 달 및 며칠을 얻을 수 있습니다.
SELECT
username
,date_of_birth
,DATE_FORMAT(CURDATE(), '%Y') - DATE_FORMAT(date_of_birth, '%Y') - (DATE_FORMAT(CURDATE(), '00-%m-%d') < DATE_FORMAT(date_of_birth, '00-%m-%d')) AS years
,PERIOD_DIFF( DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(date_of_birth, '%Y%m') ) AS months
,DATEDIFF(CURDATE(),date_of_birth) AS days
FROM users
당신은 또한 이것을 시도 할 수 있습니다 :
select MONTH(NOW())-MONTH(table_date) as 'Total Month Difference' from table_name;
또는
select MONTH(Newer_date)-MONTH(Older_date) as 'Total Month Difference' from table_Name;
INS_FRM으로 시작 날짜가 주어진 간단한 답변 및 INS_TO로 종료 날짜
SELECT convert(TIMESTAMPDIFF(year, ins_frm, ins_to),UNSIGNED) as yrs,
mod(TIMESTAMPDIFF(MONTH, ins_frm, ins_to),12) mnths
FROM table_name
즐기다 :)))
이 시도
SELECT YEAR(end_date)*12 + MONTH(end_date) - (YEAR(start_date)*12 + MONTH(start_date))
이 쿼리는 나를 위해 작동했습니다 :)
SELECT * FROM tbl_purchase_receipt
WHERE purchase_date BETWEEN '2008-09-09' AND '2009-09-09'
단순히 두 개의 날짜가 필요하고 그들 사이의 값을 검색합니다.