Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 04/08/2011, 14h32   #1
Membre à l'essai
 
Inscription : janvier 2006
Messages : 120
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 120
Points : 24
Points : 24
Par défaut valeur absurde datediff

Salut,

J'ai un petit problème que je n'arrive pas à comprendre. J'ai une table toute simple contenant 2 colonnes DatNAI et DatPres dont le type est DATE.
Lorsque je fais un DATEDIFF sur ces 2 colonnes j'ai des valeurs totalement absurdes.

DatNAI | DatPres
1923-07-17 | 1994-07-26
1955-03-24 | 2001-03-15
...

Code :
1
2
 
SELECT DATEDIFF(DtPres,DtNai) FROM export
En sortie, j'ai :
25942
16793
...

Je ne comprends pas du tout ces valeurs. Où est mon erreur ?

Merci.
Jarod51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 14h55   #2
Membre Expert
 
Avatar de Yanika_bzh
 
Homme Yannick
Ingénieur Etudes & Developpements
Inscription : février 2006
Messages : 1 125
Détails du profil
Informations personnelles :
Nom : Homme Yannick
Localisation : France, Deux Sèvres (Poitou Charente)

Informations professionnelles :
Activité : Ingénieur Etudes & Developpements
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : février 2006
Messages : 1 125
Points : 1 670
Points : 1 670
Le résultat est le nombre de jours de différence

25942 équivaut à peu près à 71 ans, or 1994-1923 c'est à peu près de cet acabit

16793 équivaut à peu près à 46 ans, ce qui est compatible avec vos dates1955 - 2001
__________________
Dans la connaissance du monde, ceux qui ne savent rien en savent toujours autant que ceux qui n'en savent pas plus qu'eux. (Pierre Dac)
Yanika_bzh est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 14h57   #3
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 009
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 009
Points : 18 282
Points : 18 282
Envoyer un message via MSN à CinePhil
DATEDIFF retourne le nombre de jours entre deux dates.
Un rapide calcul : 1994 - 1923 = 71 ans x 365 jours = 25 915 jours. Les jours de chaque année + les années bissextiles et on doit arriver à 25 942 jours non ?

Que cherches-tu à calculer ?
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 15h02   #4
Membre à l'essai
 
Inscription : janvier 2006
Messages : 120
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 120
Points : 24
Points : 24
salut,
Merci pour vos réponses.

Je n'avais pas fais le rapprochement que c'était le nombre de jours en sortie. En fait, je voulais calculer l'âge de la personne en faisant un DATEDIFF pour qu'il me retourne une valeur en années, pas en jours.

D'ailleurs, peut-on avoir le résultat en années ? j'ai essayé de rajouter le paramètre YEAR à la fin ça sort en erreur
Jarod51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 15h12   #5
Membre à l'essai
 
Inscription : janvier 2006
Messages : 120
Détails du profil
Informations forums :
Inscription : janvier 2006
Messages : 120
Points : 24
Points : 24
j'ai finalement trouvé comment faire, je poste le code sql :

Code :
SELECT EXTRACT(YEAR FROM (FROM_DAYS(DATEDIFF(DtPres,DtNai))))+0 AS age FROM export;
Jarod51 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 15h36   #6
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 009
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 009
Points : 18 282
Points : 18 282
Envoyer un message via MSN à CinePhil
Voici la formule de SQLPro pour calculer un âge en SQL :
Code :
SELECT CAST(CURRENT_TIMESTAMP - DATE_NAISSANCE AS FLOAT) / 365.2425 AS AGE_AN_DECIMAL
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 15h56   #7
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
Cette formule ne devrait pas être juste car elle utilise un nombre de jour moyen par an.
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 16h18   #8
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 009
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 009
Points : 18 282
Points : 18 282
Envoyer un message via MSN à CinePhil
Le nombre de jours moyen tient compte des années bissextiles et du fait qu'il n'y a pas d'année bissextile tous les 400 ans, comme ce fut le cas en 2000.
Bien sûr si vous prenez comme date de départ le 4 août 2010 à 16h00 et que vous voulez calculer l'âge le 4 août 2011 à 16h01, il faudra une procédure plus précise que cette approximation mais si vous voulez calculer avec une assez grande précision l'âge par exemple d'un internaute, ça fonctionne.

Le plus embêtant avec MySQL est que cet imbécile de SGBD ne sait pas "caster" en FLOAT !

Il faut faire ceci, avec un décalage d'au moins un an + 1 jour puisque DATEDIFF ne compte que la partie date, même avec une donnée en DATETIME :
Code :
SELECT DATEDIFF('2011-08-02', '2010-08-01') / 365.2425 AS AGE_AN_DECIMAL
Résultat => 1.0021
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 16h23   #9
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
Ce nombre moyen tient compte des années bissextiles, je suis d'accord.

Cependant le fait de compter 365.2425 jours par an entre 2 dates est faux car chaque année à un nombre de jours propre. Le calcul de l'age doit précisément tenir compte des années traversées et de leur nombre de jours exact (365 ou 366) ! L'age retourné par cette expression n'est donc pas toujours juste.

Code :
SELECT FLOOR(DATEDIFF('2009-05-29', '1992-05-29') / 365.2425)
=> 16 alors que la personne a 17 ans
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 16h57   #10
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 11 009
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations professionnelles :
Activité : Ingénieur d'études en informatique
Secteur : Enseignement

Informations forums :
Inscription : août 2006
Messages : 11 009
Points : 18 282
Points : 18 282
Envoyer un message via MSN à CinePhil
Tout ce qu'on peut dire de ces deux dates est que c'est l'anniversaire de la personne (même mois et même jour) mais elle n'aura 17 ans qu'à l'heure anniversaire. Comme j'ai dit plus haut, il faut un nombre d'années entier + au moins 1 jour pour que ça fonctionne à cause de DATEDIFF qui ne travaille que sur la partie DATE.
Faisons le calcul le lendemain:
Code :
SELECT FLOOR(DATEDIFF('2009-05-30', '1992-05-29') / 365.2425)
Résultat : 17
__________________
Philippe Leménager. Ingénieur d'étude à l'École Nationale de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
À la maison comme au bureau, j'utilise Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est déconnecté   Envoyer un message privé Réponse avec citation 01
Vieux 04/08/2011, 17h21   #11
ced
Rédacteur/Modérateur

 
Avatar de ced
 
Homme Cédric Duprez
Inscription : avril 2002
Messages : 3 823
Détails du profil
Informations personnelles :
Nom : Homme Cédric Duprez
Âge : 36
Localisation : France, Loiret (Centre)

Informations professionnelles :
Secteur : Agroalimentaire - Agriculture

Informations forums :
Inscription : avril 2002
Messages : 3 823
Points : 6 437
Points : 6 437
La question a été traitée par des fonctions qui gèrent tous les cas dans les sources MySQL...
Y'a qu'à se servir .
__________________
Rédacteur / Modérateur SGBD
Mes tutoriels et la FAQ MySQL

----------------------------------------------------
Pensez aux balises code et au tag
Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça
ced est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 04/08/2011, 17h22   #12
Membre Expert
 
Inscription : mars 2005
Messages : 1 565
Détails du profil
Informations personnelles :
Âge : 29
Localisation : France, Haute Garonne (Midi Pyrénées)

Informations forums :
Inscription : mars 2005
Messages : 1 565
Points : 2 178
Points : 2 178
Citation:
Envoyé par CinePhil Voir le message
Tout ce qu'on peut dire de ces deux dates est que c'est l'anniversaire de la personne (même mois et même jour) mais elle n'aura 17 ans qu'à l'heure anniversaire. Comme j'ai dit plus haut, il faut un nombre d'années entier + au moins 1 jour pour que ça fonctionne à cause de DATEDIFF qui ne travaille que sur la partie DATE.
Faisons le calcul le lendemain:
Code :
SELECT FLOOR(DATEDIFF('2009-05-30', '1992-05-29') / 365.2425)
Résultat : 17
Toujours pas d'accord . Rajouter un jour est erroné.

Imaginons la partie heure avec :

naissance : 1992-05-29 00:00
heure actuelle : 2009-05-29 00:00

La personne doit avoir 17 ans à l'heure actuelle car 17 années séparent ces deux date(time). Il n'y a pas besoin d'attendre le 2009-05-30 00:00. Le problème soulevé par mon exemple provient du nombre de jour moyen utilisé dans la formule et certainement pas de la borne de fin utilisée !

La manie de vouloir ajouter un jour pour la gestion des intervalles de date(time) vient de la mauvaise utilisation qu'on fait des colonnes qui bornent les intervalles. Je pense que vous faites l'erreur que je vois souvent dans ce cas. A savoir que vous considérer la borne de fin inclusive.

Exemple si je veux stocker une période correspondant à la journée du 1er janvier 2011, je stocke dans ma table :
Début : 2011-01-01 00:00
Fin : 2011-01-02 00:00

Et non
Début : 2011-01-01 00:00
Fin : 2011-01-01 00:00

J'ai vu cette mauvaise pratique un nombre incalculable de fois et les calculs de durée devaient systématiquement rajouter 1 jour pour être juste. Mais c'est la donnée de borne de fin stockée qui est fausse. Vous allez me dire que c'est évident quand on utilise un datetime mais ca devrait être de même en utilisant le type date.

Je fais peut être fausse piste en extrapolant sur votre exemple de calcul d'âge mais je pense ne pas me tromper.

Qu'en pensez-vous ?
vmolines est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 10h36.


 
 
 
 
Partenaires

Hébergement Web