Czekam na obliczenie liczby miesięcy między 2 pól daty.Różnica w miesiącach między datami w MySQL
Czy jest lepszy sposób niż uzyskanie znacznika czasu unix i dzielenie przez 2 592 000 (sekundy) i zaokrąglanie w górę w MySQL?
Czekam na obliczenie liczby miesięcy między 2 pól daty.Różnica w miesiącach między datami w MySQL
Czy jest lepszy sposób niż uzyskanie znacznika czasu unix i dzielenie przez 2 592 000 (sekundy) i zaokrąglanie w górę w MySQL?
Funkcja DATEDIFF może podać liczbę dni między dwiema datami. Co jest dokładniejsze, od kiedy ... jak definiujesz miesiąc? (28, 29, 30 lub 31 dni?)
To zależy od tego, jak chcesz zdefiniować # miesięcy. Odpowiedz na te pytania: "Jaka jest różnica w miesiącach: 15 lutego 2008 r. - 12 marca 2009 r.". Czy jest zdefiniowany przez czysty czas # dni, który zależy od lat przestępnych - w którym miesiącu jest, lub tego samego dnia poprzedniego miesiąca = 1 miesiąc.
Obliczenia na Dniach:
15 luty -> 29 (rok przestępny) = 14 01 marca, 2008 + 365 = 01 marca 2009. Mar 1 -> Mar 12 = 12 dni. 14 + 365 + 12 = 391 dni. Razem = 391 dni/(Śr dni w miesiącu = 30) = 13,03333
Obliczenie miesięcy:
15 lut 2008 - 15 lutego 2009 = 12 15 lutego -> mar 12 = mniej niż 1 miesiąc Razem = 12 miesięcy lub 13 czy 15 lutego - 12 marca uważany jest za 'przeszłość miesięcy'
z podręcznika MySQL:
PERIOD_DIFF (P1, P2)
Zwraca liczbę miesięcy między okresami P1 i P2. P1 i P2 powinny mieć format YYMM lub RRRRMM. Zauważ, że argumenty okresu P1 i P2 nie są wartościami daty.
mysql> SELECT PERIOD_DIFF (200802,200703); -> 11
Więc może to być możliwe, aby zrobić coś takiego:
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;
Gdzie D1 i D2 są wyrażenia data.
musiałem użyć jeśli() oświadczenia, aby upewnić się, że było kilka miesięcy dwie cyfry jak 02 zamiast 2.
SELECT *
FROM emp_salaryrevise_view
WHERE curr_year Between '2008' AND '2009'
AND MNTH Between '12' AND '1'
Czy istnieje lepszy sposób? tak. Nie używaj znaczników czasu MySQL. Poza tym, że zajmują 36 Bajtów, nie są w ogóle wygodne do pracy. Polecam używanie dat Juliańskich i sekund od północy dla wszystkich wartości daty/czasu. Można je łączyć, tworząc UnixDateTime.Jeśli jest przechowywany w DWORD (unsigned 4 Byte Integer), to data sięga aż do 2106 może być zapisana jako sekunda od epoc, 01/01/1970 DWORD max val = 4 294 967 295 - DWORD może pomieścić 136 lat Sekund
Daty Julian są bardzo przyjemne w pracy przy obliczaniu daty Wartości UNIXDateTime dobrze sprawdzają się przy dokonywaniu obliczeń Data/Czas Nie warto też patrzeć, więc używam znaczników czasu, kiedy potrzebuję kolumny, którą będę nie licząc się z dużymi kalkulacjami, ale chcę uzyskać natychmiastowe wskazanie.
Nawrócenie na język juliański iz powrotem można wykonać bardzo szybko w dobrym języku. Używając wskaźników mam go do około 900 Clks (jest to również konwersja z STRINGa na INTEGER oczywiście)
Kiedy dostajesz się do poważnych aplikacji, które używają informacji Data/Czas, takich jak na przykład rynki finansowe, daty juliańskie są de facto.
gdzie Czy dostałeś informację o * tym, że zajmują 36 bajtów *? Wymagania dla pamięci podręcznej MySQL dla kolumny TIMESTAMP wynoszą ** 4 bajty **. http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html – poncha
już teraz zacznij planowanie błędu Y2106! ;-) – ErichBSchulz
oblicza miesiące między dwiema datami.
Na przykład, do obliczania różnicy między jest() i kolumnę czasową your_table:
select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;
Każdy pomysł, co robi, gdy może to być 11 miesięcy i 1 dzień, więc 12 miesięcy, ale jeśli zmienisz na 30 dni miesięcy, to nadal będzie 11? –
11 miesięcy i 1 dzień zwróci 11 miesięcy z powyższym przykładem. PERIOD_DIFF nie ma poczucia 30 względem 31 dni. –
zapytaniu są następująco:
select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where..
daje szereg miesiące kalendarzowe, ponieważ Stworzono datestamp na rekordzie klienta, pozwalając MySQL na wewnętrzną selekcję miesięcy.
To zapytanie pracował dla mnie :)
SELECT * FROM tbl_purchase_receipt
WHERE purchase_date BETWEEN '2008-09-09' AND '2009-09-09'
To po prostu wziąć dwie daty i pobiera wartości między nimi.
całkowicie niepoprawna odpowiedź, chce liczbę miesięcy –
Wolę w ten sposób, ponieważ evryone go zrozumie wyraźnie na pierwszy rzut oka:
SELECT
12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months
FROM
tab;
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
używam również PERIODDIFF. Aby uzyskać roku i miesiąca od daty, używam funkcji EXTRACT:
SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table;
Niesamowite! Wykorzystuje on o 50% mniej czasu niż metoda "DATE_FORMAT", dzięki! +1 –
Tutaj dla unix timestamp 'WYBIERZ PERIOD_DIFF (EKSTRAKT (YEAR_MONTH FROM TERAZ()), EKSTRAKT (YEAR_MONTH OD FROM_UNIXTIME (czas,"% Y% m% d "))) AS miesięcy od your_table;' – Smolla
To jest niepoprawne, PERIOD_DIFF' nie uwzględnia wartości dni, więc obliczasz liczbę miesięcy zaokrąglonych w górę do najbliższego miesiąca, jeśli jest mniej niż cała liczba miesięcy. Powinieneś edytować swoją odpowiedź, aby to wyjaśnić. – rgvcorley
wykonanie tego kodu i będzie utworzyć funkcję datedeifference które dadzą Ci różnicę w formacie daty rrrr-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;
Czy sądzisz, że mógłbyś trochę wyczyścić i skomentować swój kod, więc jest to trochę bardziej zrozumiałe? Dzięki –
Dziwię ten nie został jeszcze wymienić:
Zapraszamy do obejrzenia funkcji w MySQL TIMESTAMPDIFF().
Co to pozwala zrobić to wprost w dwóch TIMESTAMP
lub DATETIME
wartości (lub nawet DATE
jak MySQL będzie automatycznie przeliczać), jak również jednostka czasu chcesz oprzeć na różnicę.
Można określić MONTH
jako jednostki w pierwszym parametrze:
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-04')
-- Outputs: 0
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-15')
-- Outputs: 1
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-12-16')
-- Outputs: 7
Zasadniczo dostaje numer miesięcy, które upłynęły od pierwszej daty listy parametrów. To rozwiązanie automatycznie rekompensuje różną liczbę dni w każdym miesiącu (28,30,31), a także biorąc pod uwagę lata przestępne —, nie musisz się martwić o nic z tego.
To trochę bardziej skomplikowane, jeśli chcesz wprowadzić dokładność dziesiętną liczby miesięcy upłynął, ale tutaj jest to, jak można to zrobić:
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
)
Gdzie startdate
i enddate
są twoje parametry tej pory, czy to z dwóch dat kolumn w tabeli lub parametrów wejściowych ze skryptu:
Przykłady:
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
To jest poprawna odpowiedź, wszystkie notatki do wpisu 'PERIODDIFF' na temat wybranej odpowiedzi są bardzo niefortunne – rgvcorley
Dzięki, w moim przypadku potrzebowałem włącznie dat, więc zastępuję wszystkie" enddate "przez" date_add (enddate, interwał 1 dzień) ". Wówczas od 2014-03-01 do 2014-05-31 otrzymasz 3,00 zamiast 2,97 –
Dziękuję bardzo .....special thanx dla "Dokładność miesiąca z dokładnością:". Jesteś gwiazdą mysql – Vidhi
można uzyskać lat, miesięcy i dni w ten sposób:
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
Potrzebowałem miesiąc różnicy z precyzją. Chociaż rozwiązanie Zane Bien jest we właściwym kierunku, jego drugi i trzeci przykład dają niedokładne wyniki. Dzień w lutym podzielony przez liczbę dni w lutym nie jest równy jednemu dniu w maju podzielonemu przez liczbę dni w maju. Tak więc drugi przykład powinien wyprowadzić ((31-5 + 1)/31 + 13/30 =) 1,3043 a trzeci przykład ((29-27 + 1)/29 + 2/30 + 3 =) 3,1701.
skończyło się następujące zapytanie:
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
Można również spróbować tego:
select MONTH(NOW())-MONTH(table_date) as 'Total Month Difference' from table_name;
LUB
select MONTH(Newer_date)-MONTH(Older_date) as 'Total Month Difference' from table_Name;
Ponieważ wiele odpowiedzi tutaj Pokazują, " odpowiednia odpowiedź zależy od tego, czego dokładnie potrzebujesz. W moim przypadku muszę w rundzie do najbliższej liczby całkowitej.
Weź pod uwagę następujące przykłady: 1 stycznia -> 31 stycznia: 0 miesięcy i prawie 1 miesiąc. 1 stycznia -> 1 lutego? Jest to 1 miesiąc i dokładnie 1 miesiąc.
Aby uzyskać liczbę całych miesięcy, przeznaczenie:
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-01-31'); => 0
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-01'); => 1
dostać zaokrąglone czas w miesiącach, można użyć:
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
To jest z dokładnością do +/- 5 dni i dla zakresów powyżej 1000 lat. Odpowiedź Zane'a jest oczywiście bardziej dokładna, ale jest zbyt szczegółowa, jak mi się podoba.
[PERIODDIFF] (http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_period-diff) może dokładnie obliczyć liczbę miesięcy. –
"Bardziej dokładne" jest niewiarygodnie subiektywne, jeśli chodzi o daty. Jeśli na przykład jesteś w firmie, która ma cykle miesięczne, które muszą wiedzieć, ile miesięcy znajduje się między dwiema datami, może być ważniejsza niż liczba dni z tego samego powodu, który podano powyżej. Jak długi jest miesiąc? Jeśli potrzebuję liczenia miesięcy, nie mogę po prostu podzielić przez 30. –
To nie jest poprawna odpowiedź; powinieneś oznaczyć odpowiedź [Max's] (http://stackoverflow.com/a/562477/389034) poniżej. –