Muszę obliczyć wiek "klienta" od daty urodzenia.Jak uzyskać wiek z pola D.O.B w MySQL?
Próbowałem użyć następującego:
DATEDIFF (rok, customer.dob "2010-01-01");
Ale to nie działa.
Wszelkie pomysły? WIEM, że to będzie coś prostego!
Dzięki
Muszę obliczyć wiek "klienta" od daty urodzenia.Jak uzyskać wiek z pola D.O.B w MySQL?
Próbowałem użyć następującego:
DATEDIFF (rok, customer.dob "2010-01-01");
Ale to nie działa.
Wszelkie pomysły? WIEM, że to będzie coś prostego!
Dzięki
kilka sposobów:
select DATEDIFF(customer.dob, '2010-01-01')/365.25 as age
SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(customer.dob,'2010-01-01')), ‘%Y’)+0 AS age
Nadzieja to pomaga
SELECT DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(dob, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(dob, '00-%m-%d')) AS age
Ten jest lepszy niż zaakceptowana odpowiedź. Dzięki za publikację! –
Dzięki. Używałbym 'year (x)' zamiast 'date_format (x, '% Y'), w przeciwnym razie jest wspaniale. – Tobia
odpowiedź Bryan Denny jest bardziej poprawna niż zaakceptowanej odpowiedzi (nie był pewien, jak umieścić to w innym miejscu niż nowa odpowiedź, to jest mój pierwszy raz na StackOverflow).
Marcos' pierwsza próba:
select DATEDIFF(customer.dob, '2010-01-01')/365.25 as age
będzie najpierw uzyskując wynik negatywny (argumenty do DateDiff są w złej kolejności), a po drugie będzie produkować niedokładne wyniki dla niektórych terminach, np:
SELECT DATEDIFF('2010-05-11','1984-05-11')/365.25 AS age
daje wynik:
25.9986
nie po prostu można zawsze zaokrąglić, ponieważ spowoduje to również niedokładne wyniki dla innych danych wejściowych.
Marcos' Druga próba:
SELECT DATE_FORMAT(FROM_DAYS(DATEDIFF(customer.dob,'2010-01-01')), ‘%Y’)+0 AS age
Znowu, argumenty są w niewłaściwej kolejności, ale tym razem zamiast po prostu tworząc liczbę ujemną, FROM_DAYS() funkcja nie działa poprawnie z wejściem ujemnym. Po drugie, jeśli przyjrzymy się bliżej wyjścia z FROM_DAYS() Funkcja:
select from_days(datediff('2010-09-16','1984-05-11'));
Rezultatem powyższego jest:
0026-05-08
która jest dosłownie „8 maja, Rok 26 (po 0) ". Pamiętaj, że w przypadku typów datetime nie ma miesiąca "0", więc jeśli chcesz użyć tego formatu do mierzenia przedziału czasu zawierającego miesiące, musisz odjąć 1 od miesiąca. Podobnie ze składnikiem dzień, nie ma „0”, więc wynik nie jest to, czego można spodziewać się tego problemu, gdy dzieje się data urodzin:
select from_days(datediff('2010-05-11','1984-05-11'));
produkuje:
0025-12-31
co jeśli skracamy używając formatowania daty Marcos daje nam "25", co jest nieprawidłową kalkulacją wieku.
Odpowiedź Bryana Denny jest poprawna we wszystkich tych skrajnych przypadkach. Jego formuła jest sprytna:
SELECT DATE_FORMAT(reference, '%Y') - DATE_FORMAT(birthdate, '%Y') - (DATE_FORMAT(reference, '00-%m-%d') < DATE_FORMAT(birthdate, '00-%m-%d')) AS age
Pierwsza część oblicza różnicę w latach między tymi dwoma datami. Jeśli więc weźmiemy odpowiednio "2010" i "1984" jako odniesienia i datę urodzenia, wynikiem jest "26". W drugiej części oblicza się w istocie "Czy miesiąc i dzień z datą urodzenia występują po miesiącu i dniu odniesienia?" Jeśli tak, to "jeszcze się nie wydarzyło", więc musimy odjąć dodatkową 1 od różnicy roku, aby to zrekompensować. Jest to uwzględnione w wyniku porównania <, które zwraca 1, jeśli jest prawdziwe, a 0, jeśli jest fałszywe.
Tak, pełne przykładów:
1)
Reference date: 2010-05-10;
Birthdate: 1984-05-11
Year difference = 2010 - 1984 = 26
Month and day comparison: May 10th < May 11th? Yes => subtract an additional year
Calculated age: 25 years
2)
Reference date: 2010-05-11;
Birthdate: 1984-05-11
Year difference = 2010 - 1984 = 26
Month and day comparison: May 11th < May 11th? No => subtract 0
Calculated age: 26 years
Mam nadzieję, że to sprawia, że rzeczy bardziej zrozumiałe dla ludzi!
najszybszym zapytaniem jest to, co @almaruf dostarczył – user1016265
Jest to najprostszy mogę wymyślić do tej pory:
SELECT FLOOR(ABS(DATEDIFF(d, CURRENT_TIMESTAMP, dob))/365.25) AS age
Najpierw otrzymujemy różnicę dat w dni, a następnie przekształcić go lat, a następnie obcina FLOOR do części całkowitej liczby.
Poniższy sql działa dobrze dla mnie. Zawsze używaj CURRENT_DATE
z opcją dob, aby obliczyć rzeczywisty wiek.
SELECT
DATE_FORMAT(
FROM_DAYS(
DATEDIFF(CURRENT_DATE, dob)
),
'%y Years %m Months %d Days'
) AS age
FROM
users
Przyjęto podana data jest większa niż bieżąca,
1.Find łączna liczba dni/b bieżącej daty i dany dzień.
->DATEDIFF(NOW(),'1988-05-01')
2.Find no lat od dni nie oblicza.
->DATEDIFF(NOW(),'1988-05-01')/365.25
3. wiek nie powinien być od lat przeprowadzać osoby. Aby to uzyskać, możemy użyć "podłogi" do obliczonej liczby lat.
->FLOOR(DATEDIFF(NOW(),'1988-05-01')/365.25)
przykład: SELECT FLOOR(DATEDIFF(NOW(),'1988-05-01')/365.25) AS age;
Gratulacje, właśnie skopiowałeś zaakceptowaną odpowiedź, która została wybrana jako pierwsza odpowiedź wyjaśnia, dlaczego jest źle. –
Proszę nie po prostu pisać kodu. Podaj wyjaśnienia lub informacje na temat Twojego kodu lub użycia. Na przykład zobacz [ta odpowiedź] (http://stackoverflow.com/a/16893057/756941). – NAZIK
Dzięki za właściwy kierunek. –
Zastosowanie Mysql zalecane:
TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age;
użycia w zapytaniu:
SELECT name, dob, TIMESTAMPDIFF(YEAR, dob, CURDATE()) AS age FROM pet;
Ref http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html
Jest to niepoprawne, gdy urodziny mają miejsce samego dnia, więc powinieneś dodać 1 do bieżącego dnia. – user114111121
W zależności od potrzeb - dostępne funkcje int i float.
- Twoje reguły biznesowe mogą się różnić więc dostosować odpowiednio
DROP FUNCTION IF EXISTS `age`;
CREATE FUNCTION `age` (
`pdate_begin` DATE,
`pdate_end` DATETIME
) RETURNS INT(11) UNSIGNED
COMMENT 'Calc age between two dates as INT'
DETERMINISTIC NO SQL SQL SECURITY DEFINER
RETURN floor(datediff(pdate_end, pdate_begin)/365.25) ;
DROP FUNCTION IF EXISTS `age_strict`;
CREATE FUNCTION `age_strict` (
`pdate_begin` DATE,
`pdate_end` DATETIME
) RETURNS decimal(10,4)
COMMENT 'Calc age between two dates as DECIMAL .4'
DETERMINISTIC NO SQL SQL SECURITY DEFINER
RETURN round(datediff(pdate_end, pdate_begin)/365.25, 4) ;
-- test harness
select
age(dob, now()) as age_int,
age_strict(dob, now()) as age_dec
from customer
where dob is not null
order by age(dob,now()) desc;
-- test results
dob, age_int, age_dec
1981-01-01 00:00:00 33 33.9713
1987-01-09 00:00:00 27 27.9507
2014-11-25 00:00:00 0 0.0739
DELIMITER $$ DROP FUNCTION IF EXISTS `test`.`_AGE` $$
CREATE FUNCTION `_AGE`(in_dob datetime) RETURNS VARCHAR(100)
NO SQL
BEGIN
DECLARE l_age VARCHAR(100);
DECLARE YEARS INT(11);
DECLARE MONTHS INT(11);
DECLARE DAYS INT(11);
DECLARE DIFFS FLOAT;
SET DIFFS=DATEDIFF(CURRENT_DATE(),in_dob) /365.25;
SET YEARS=FLOOR(DIFFS) ;
SET MONTHS=FLOOR((DIFFS - YEARS)*365.25/30.4375) MOD 12;
SET DIFFS=((DIFFS - YEARS)*365.25/30.4375);
SET DAYS=CEIL(((DIFFS-MONTHS)*30.4375)) MOD 31;
SET l_age=CONCAT(YEARS, " Year ",MONTHS," Month ",DAYS," Days");
RETURN(l_age);
END $$
DELIMITER ;
SELECT _Age(CAST('1980-07-16' AS DATE));
Dlaczego Twoje rozwiązanie jest lepsze niż starsze najczęściej wybierane odpowiedzi? – Marki555
Dzięki, dałem mi pomysł, jak uzyskać funkcję wiekową, działającą w mojej aplikacji. –
DELIMITER $$ DROP FUNCTION IF EXISTS `test`.`__AGE` $$
CREATE FUNCTION `_AGE`(in_dob datetime) RETURNS VARCHAR(100)
NO SQL
BEGIN
DECLARE l_age VARCHAR(100);
DECLARE YEARS INT(11);
DECLARE MONTHS INT(11);
DECLARE DAYS INT(11);
DECLARE DIFFS FLOAT;
SET DIFFS=DATEDIFF(CURRENT_DATE(),in_dob) /365.25;
SET YEARS=FLOOR(DIFFS) ;
SET MONTHS=FLOOR((DIFFS - YEARS)*365.25/30.4375) MOD 12;
SET DIFFS=((DIFFS - YEARS)*365.25/30.4375);
SET DAYS=CEIL(((DIFFS-MONTHS)*30.4375)) MOD 31;
RETURN(CONCAT(YEARS, " Year ",MONTHS," Month ",DAYS," Days"));
END $$
DELIMITER ;
SELECT __Age(CAST('1980-07-16' AS DATE));
Witamy w SO Ravi Shankar. Bez względu na to, czy to rozwiązanie działa, lepiej byłoby dodać opis zapytań. W ten sposób OP i każdy, kto to czyta, będzie lepiej rozumieć, co chcesz osiągnąć. – dhh
DATE_FORMAT(FROM_DAYS(DATEDIFF(CURDATE(),'1869-10-02')), '%Y')+0 AS age;
Przede zapytania MySQL zostało przetestowane i sprawdzone. Daje ci dokładny wiek w latach. Wziąłem ten pomysł z odpowiedzi Marcosa i zmieniłem parametry DATEDIFF().
to jest doskonałe! wielkie dzięki! –
Cieszę się, że ci pomogło. Proszę oznaczyć odpowiedź jako zaakceptowaną, aby inni mogli z niej korzystać w przyszłości :-) –
Jestem ciekawy: po co jest 0,25? – ryanprayogo