J'ai un tableau répertoriant les personnes avec leur date de naissance (actuellement un nvarchar (25))
Comment puis-je convertir cela en une date, puis calculer leur âge en années?
Mes données se présentent comme suit
ID Name DOB
1 John 1992-01-09 00:00:00
2 Sally 1959-05-20 00:00:00
J'aimerais voir:
ID Name AGE DOB
1 John 17 1992-01-09 00:00:00
2 Sally 50 1959-05-20 00:00:00
Réponses:
Il y a des problèmes avec les années / jours bissextiles et la méthode suivante, voir la mise à jour ci-dessous:
MISE À JOUR voici quelques méthodes plus précises:
MEILLEURE MÉTHODE POUR LES ANNÉES EN INT
vous pouvez changer ci - dessus
10000
pour10000.0
et obtenir des décimales, mais il ne sera pas aussi précis que la méthode ci - dessous.MEILLEURE MÉTHODE POUR LES ANNÉES EN DÉCIMAL
la source
GETDATE()
) le '2013-07-04 23:59:59', il dit que je J'ai 27 ans, alors qu'à ce moment, je ne suis pas encore. Exemple de code:declare @startDate nvarchar(100) = '1986-07-05 00:00:00' declare @endDate nvarchar(100) = '2013-07-04 23:59:59' SELECT DATEDIFF(hour,@startDate,@endDate)/8766.0 AS AgeYearsDecimal ,CONVERT(int,ROUND(DATEDIFF(hour,@startDate,@endDate)/8766.0,0)) AS AgeYearsIntRound ,DATEDIFF(hour,@startDate,@endDate)/8766 AS AgeYearsIntTrunc
select datediff(year, '2000-01-05', '2018-01-04')
renvoie 18 et non 17 comme il se doit. J'ai utilisé l'exemple ci-dessus sous la rubrique "MEILLEURE MÉTHODE POUR LES ANNÉES EN INT" et cela fonctionne parfaitement. Merci!Je dois jeter celui-ci là-bas. Si vous convertissez la date en utilisant le style 112 (aaaammjj) en un nombre, vous pouvez utiliser un calcul comme celui-ci ...
(aaaaMMjj - aaaaMMjj) / 10000 = différence en années complètes
production
la source
code: SELECT [Age] = (0+ FORMAT(@as_of,'yyyyMMdd') - FORMAT(@bday,'yyyyMMdd') ) /10000 --The 0+ part tells SQL to calc the char(8) as numbers
J'utilise cette requête dans notre code de production depuis près de 10 ans:
la source
DATEDIFF(yy, @BirthDate, GETDATE()) - CASE WHEN (MONTH(@BirthDate) >= MONTH(GETDATE())) AND DAY(@BirthDate) > DAY(GETDATE()) THEN 1 ELSE 0 END
CASE WHEN (MONTH(@date) > MONTH(GETDATE())) OR (MONTH(@date) = MONTH(GETDATE()) AND DAY(@date) > DAY(GETDATE())) THEN 1 ELSE 0 END
La plupart des solutions ci-dessus sont donc erronées. DateDiff (yy, @ Dob, @PassedDate) ne tiendra pas compte du mois et du jour des deux dates. Prendre également les pièces de fléchettes et comparer ne fonctionne que si elles sont correctement ordonnées.
LE CODE SUIVANT FONCTIONNE ET EST TRÈS SIMPLE:
la source
0925
(ou925
). Il fait la même chose avec la date actuelle (comme le 16 décembre devient1216
) et vérifie ensuite si la valeur entière DoB est déjà passée. Pour créer cet entier, le mois doit être multiplié par 100.(CONVERT(int,CONVERT(char(8),@Now,112))-CONVERT(char(8),@Dob,112))/10000
Vous devez tenir compte de la manière dont la commande dateiff tourne.
Ce que j'ai adapté d' ici .
Notez qu'il considérera le 28 février comme l'anniversaire d'un bondissant pour les années non bissextiles, par exemple, une personne née le 29 février 2020 sera considérée comme âgée de 1 an le 28 février 2021 au lieu du 01 mars 2021.
la source
SELECT DATEDIFF(year, DOB, getdate()) + CASE WHEN (DATEADD(year,DATEDIFF(year, DOB, getdate()) , DOB) > getdate()) THEN - 1 ELSE 0 END)
MODIFIER: CETTE RÉPONSE EST INCORRECTE. Je le laisse ici comme un avertissement à toute personne tentée d'utiliser
dayofyear
, avec une autre modification à la fin.Si, comme moi, vous ne voulez pas diviser par fractions de jours ou risquer des erreurs d'arrondi / d'année bissextile, j'applaudis le commentaire de @Bacon Bits dans un message ci-dessus https://stackoverflow.com/a/1572257/489865 où il dit:
Il propose ensuite:
Il y a plusieurs suggestions ici impliquant la comparaison du mois et du jour (et certains se trompent, sans tenir compte du
OR
aussi correctement ici!). Mais personne n'a offertdayofyear
, ce qui semble si simple et beaucoup plus court. J'offre:[Note: Nulle part dans SQL BOL / MSDN ce qui
DATEPART(dayofyear, ...)
renvoie réellement documenté! Je crois comprendre que c'est un nombre compris entre 1 et 366; plus important encore, il ne change pas selon les paramètres régionaux selonDATEPART(weekday, ...)
&SET DATEFIRST
.]EDIT: Pourquoi se
dayofyear
passe- t -il mal ? Comme l'a commenté l'utilisateur @AeroX, si la date de naissance / début est après février dans une année non bissextile, l'âge est incrémenté un jour plus tôt lorsque la date actuelle / de fin est une année bissextile, par exemple'2015-05-26'
,'2016-05-25'
donne un l'âge de 1 alors qu'il devrait encore être de 0. La comparaisondayofyear
de différentes années est clairement dangereuse. Donc utiliserMONTH()
etDAY()
est nécessaire après tout.la source
DayOfYear
méthode.dayofyear
, mais clairement éditée pour montrer pourquoi elle ne va pas. J'espère que cela convient.Puisqu'il n'y a pas une réponse simple qui donne toujours l'âge correct, voici ce que j'ai trouvé.
Cela obtient la différence d'année entre la date de naissance et la date actuelle. Ensuite, il soustrait un an si la date de naissance n'est pas encore dépassée.
Précis à tout moment - indépendamment des années bissextiles ou de la proximité de la date de naissance.
Le meilleur de tous - aucune fonction.
la source
la source
Qu'en est-il de:
Cela n'éviterait-il pas tous ces problèmes d'arrondi, de troncature et de réglage?
la source
'1986-07-05 00:00:00'
pour DOB et'2013-07-04 23:59:59'
pour l'heure actuelle.Je crois que c'est similaire à d'autres postés ici .... mais cette solution a fonctionné pour les exemples d'année bissextile 29/02/1976 au 03/01/2011 et a également fonctionné pour le cas pour la première année .. comme 07/04 / 2011 au 07/03/2012 que le dernier a publié sur la solution des années bissextiles n'a pas fonctionné pour ce cas d'utilisation de la première année.
Trouvé ici .
la source
la source
source: http://beginsql.wordpress.com/2012/04/26/how-to-calculate-age-in-sql-server/
la source
code: SELECT [Age] = (0+ FORMAT(@ToDate,'yyyyMMdd') - FORMAT(@DOB,'yyyyMMdd') ) /10000
J'ai beaucoup réfléchi et cherché à ce sujet et j'ai 3 solutions qui
Voici les valeurs de test:
Solution 1: J'ai trouvé cette approche dans une bibliothèque js. C'est mon prefere.
Cela ajoute en fait une différence en années à la date de naissance et si elle est supérieure à la date actuelle, elle soustrait un an. Simple non? La seule chose est que la différence d'années est ici dupliquée.
Mais si vous n'avez pas besoin de l'utiliser en ligne, vous pouvez l'écrire comme ceci:
Solution 2: Celui-ci que j'ai copié à l'origine à partir de @ bacon-bits. C'est le plus simple à comprendre mais un peu long.
Il s'agit essentiellement de calculer l'âge comme nous le faisons les humains.
Solution 3: mon ami l'a remanié en ceci:
Celui-ci est le plus court mais il est le plus difficile à comprendre.
50
est juste un poids, donc la différence de jour n'est importante que lorsque les mois sont identiques.SIGN
La fonction est pour transformer n'importe quelle valeur qu'elle obtient en -1, 0 ou 1.CEILING(0.5 *
est la même queMath.max(0, value)
mais il n'y a rien de tel en SQL.la source
la source
Il y a beaucoup de 365,25 réponses ici. Rappelez-vous comment les années bissextiles sont définies:
la source
Que dis-tu de ça:
la source
Essaye ça
la source
Essayez cette solution:
la source
Cela gérera correctement les problèmes avec l'anniversaire et l'arrondissement:
la source
La solution d'Ed Harper est la plus simple que j'ai trouvée et ne renvoie jamais la mauvaise réponse lorsque le mois et le jour des deux dates sont distants d'un jour ou moins. J'ai fait une légère modification pour gérer les âges négatifs.
la source
La réponse marquée comme correcte est plus proche de l'exactitude, mais elle échoue dans le scénario suivant - où l' année de naissance est l'année bissextile et le jour après le mois de février
OU
- La solution suivante me donne des résultats plus précis.
Cela a fonctionné dans presque tous les scénarios, en considérant l'année bissextile, la date du 29 février, etc.
Veuillez me corriger si cette formule présente une lacune.
la source
floor
.la source
Voici comment je calcule l'âge en fonction d'une date de naissance et d'une date actuelle.
la source
la source
month(compare) > month(dob)
MAISday(compare) < day(dob)
, par exempleselect dbo.AgeAtDate('2000-01-14', '2016-02-12')
.la source
Qu'en est-il d'une solution avec uniquement des fonctions de date, pas de mathématiques, pas de soucis pour l'année bissextile
la source
Après avoir essayé BEAUCOUP de méthodes, cela fonctionne 100% du temps en utilisant la fonction MS SQL FORMAT moderne au lieu de convertir en style 112. Les deux fonctionneraient mais c'est le moins de code.
Quelqu'un peut-il trouver une combinaison de dates qui ne fonctionne pas? Je ne pense pas qu'il y en ait un :)
la source
Nous avons utilisé quelque chose comme ici, mais en prenant ensuite l'âge moyen:
Remarquez, le ROND est à l'extérieur plutôt qu'à l'intérieur. Cela permettra à l'AVG d'être plus précis et nous n'ARRONDONS qu'une seule fois. Le rendre plus rapide aussi.
la source
la source
la source