Mysql : nombre de jours entre deux dates pour une entrée

Mysql : nombre de jours entre deux dates pour une entrée - SQL/NoSQL - Programmation

Marsh Posté le 23-07-2014 à 23:56:16    

Bonjour,
 
Je voudrais faire un truc en SQL mais j'ai beau chercher je ne trouve pas comment écrire le truc :D
 
J'ai par exemple les dates des visites médicales par personne :
 

Code :
  1. |            Nom            |            Date                       |
  2. -----------------------------------------------------------
  3. |            Toto             |            2014-01-12            |
  4. |            Titi              |            2014-01-18            |
  5. |            Titi              |            2014-01-20            |
  6. |            Zoé             |            2014-01-25            |
  7. |            Toto             |            2014-01-29            |


 
Je voudrais faire une requête SQL pour avoir, pour chaque personne, la date entre deux visite. résultat :
Toto : 17
Titi : 2
Zoé : NULL (ou autre valeur pour ceux qui n'ont eu qu'une seule visite).
 
Je ne vois même pas comment faire.
 
Auriez vous une idée svp ?  
 
Merci !


---------------
Bha ouais mais bon, m'enfin quoi...
Reply

Marsh Posté le 23-07-2014 à 23:56:16   

Reply

Marsh Posté le 24-07-2014 à 05:44:23    

J'ai pas MySQL pour tester, mais tu peux tenter un truc du genre :
 

Code :
  1. SELECT mini.nom,
  2. CASE
  3. WHEN mini.nbVisites <= 1 THEN NULL
  4. ELSE DATEDIFF(mini.mindate, maxi.maxdate) END As nbDays
  5. FROM
  6. (SELECT nom, min(date) As mindate, COUNT(*) As nbVisites
  7. FROM Visite
  8. GROUP BY nom) As mini
  9. INNER JOIN
  10. (SELECT nom, max(date) As maxdate, COUNT(*) As nbVisites
  11. FROM Visite
  12. GROUP BY nom) As maxi ON mini.nom = maxi.nom


Message édité par Yonel le 24-07-2014 à 05:47:18
Reply

Marsh Posté le 24-07-2014 à 08:15:30    

vanquishV12: tu n'as pas une date en résultat, c'est donc normal que tu ne trouves pas... mais tu as un nombre de jours...
donc après cela va tout de suite mieux, à chercher sur internet ou dans tes cours, doc de sql...
Car si ta date est un champ de type date ou plus généralement timestamp: tu as les fonctions sql associées...
Bonne recherche, cela ne va pas être compliquer à trouver...

 

Guillaume

 


Message édité par gpl73 le 24-07-2014 à 10:13:23

---------------
mieux vaut être un con au chaud, qu'un con gelé lol
Reply

Marsh Posté le 24-07-2014 à 08:26:57    

Yonel, ta requête marche bien ?
à quoi te sert le count?
que se passe t il si tu as plus de 2 occurrences par nom?
j'ai peur que tu aies bien la nb de jours mais uniquement
entre la plus récente, et la plus ancienne, et non pas entre deux visites...
Guillaume


---------------
mieux vaut être un con au chaud, qu'un con gelé lol
Reply

Marsh Posté le 24-07-2014 à 08:31:43    

Le COUNT c'est pour gérer son cas "Zoé : NULL" qui se produit quand il y a moins de 2 visites.
 
Effectivement la requête ne fonctionne que s'il y a 2 visites uniquement. Je me suis basé sur son exemple qui a l'air comme ça. Si tu as X visites c'est déjà plus compliqué.
 
vanquishV12: Tu peux préciser si tu as des cas avec plus de 2 visites dans ton besoin ?

Reply

Marsh Posté le 24-07-2014 à 09:02:18    

En ayant une table vis :
NOM       RDV                        
gpl         2014-07-09-08.37.51.077682  
gpl         2014-07-14-08.37.56.953482  
gpl         2014-07-19-08.38.02.829309  
gpl         2014-07-24-08.38.11.330462  
u1          2014-07-24-08.38.18.207219  
u1          2014-07-19-08.38.32.708750  
u2          2014-07-19-08.38.37.252754  
u3          2014-07-19-08.38.42.100058  
u1          2014-07-23-08.38.51.582114  
u1          2014-07-22-08.38.56.435283  
u1          2014-07-14-08.39.05.139993  
u2          2014-07-14-08.39.13.652005  
u4          2014-07-14-08.39.20.788788  
 
et si tu fais une requête du style:
select a.*, date(a.rdv)-
date((SELECT max(b.rdv) FROM vis as b where a.nom = b.nom  and b.rdv <a.rdv group by b.nom)) as nb_jours_rdv        
from vis as a                                                
order by a.nom, a.rdv ;
tu obtiens :
 NOM       RDV                                                NB_JOURS_RDV  
 gpl         2014-07-09-08.37.51.077682             -  
 gpl         2014-07-14-08.37.56.953482            5    
 gpl         2014-07-19-08.38.02.829309            5    
 gpl         2014-07-24-08.38.11.330462            5    
 u1          2014-07-14-08.39.05.139993             -  
 u1          2014-07-19-08.38.32.708750            5    
 u1          2014-07-22-08.38.56.435283            3    
 u1          2014-07-23-08.38.51.582114            1    
 u1          2014-07-24-08.38.18.207219            1    
 u2          2014-07-14-08.39.13.652005             -  
 u2          2014-07-19-08.38.37.252754            5    
 u3          2014-07-19-08.38.42.100058             -  
 u4          2014-07-14-08.39.20.788788             -  
 
Guillaume
 
                                     


---------------
mieux vaut être un con au chaud, qu'un con gelé lol
Reply

Marsh Posté le 24-07-2014 à 09:30:17    

Ton approche est correcte gpl73.
 
Mais je voudrais faire une remarque à vanquishV12 :
Le fait que ce soit pas "trivial" d'écrire une requête aussi simple démontre un problème de structure.
 
Ce serait tellement plus simple si tu avais :
nom / dateVisite / dateDerniereVisite dans tes champs. Après tout une visite c'est exactement ça.
 
Je sais que c'est pas toujours facile/possible de modifier la structure de la base sans tout casser.
Mais c'est en refusant de le faire qu'on se retrouve à écrire des requêtes moches ou du code difficile à maintenir.
 
Des fois il faut savoir prendre du recul et revoir le schéma de la base. Et si tu es pas à l'aise avec la création d'un schéma de base efficient, je te conseille de lire au sujet de la méthode Merise.


Message édité par Yonel le 24-07-2014 à 09:54:44
Reply

Marsh Posté le 24-07-2014 à 10:24:37    

Bonjour,
 
Je ne peux pas modifier la structure de la base malheureusement.
 
Oui je peux avoir n visites comme 1 seule.
 
Le cas du NULL n'est pas obligatoire par contre, je ne pensais pas que ce serait si complexe.
 
Ca ca semble marcher non?
SELECT nom,DATEDIFF(MAX(date), MIN(date)) as ecart FROM vm GROUP BY nom;
 
Le résultat est bon?
 
Par contre... en la faisant je me rends compte que ce que je voudrais est encore plus compliqué car j'ai besoin du nombre de jours d'écart entre la dernière visite et... L'avant dernière :pt1cable:  
 
Merci pour vos messages c'est toujours très instructif !


---------------
Bha ouais mais bon, m'enfin quoi...
Reply

Marsh Posté le 24-07-2014 à 10:27:10    

Si tu as plus de 2 visites il faut que tu utilises l'approche de gpl73 qui gère ce cas. Le MIN/MAX ne fonctionnera pas.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed