Requete SQL recherche

Résolu
Bonjour,

j'ai une base de donnée avec une table Personne du type :

REF // est un integeur auto ingrémenté par la base
Date // est une Date de type 2009-07-22
Etat // est un varchar 6 qui peu prendre deux valeur Absent ou Retour
ID // est un varchar 50 comprenant Prénom et Nom attaché de la personne

cette table référence chaque absence et chaque retour

exemple :

1 2009-07-22 Absent Toto
2 2009-07-22 Absent Titi
3 2009-07-23 Retour Titi
4 2009-07-24 Retour Toto

je souhaiterais faire une requete qui recherche l'entré Retour de la colone Etat et me renvoye le nombre de jour absent par toto avec l'exemple du dessus il devrai me retourné Toto absent 2 jour.

problème je ne vois pas comment faire je suis dans le noir ???

Merci à vous d'éclairer ma lanterne
Configuration: Change en permanence

12 réponses

  • Votes
  • Date
  • Date décroissante
  1. Ha ben alors c'est quelquechose du genre :

    SELECT DATEDIFF(p2.Date,p1.Date)
    FROM `test` p1, `test` p2
    WHERE p1.ID='Toto' AND p1.Etat='Absent' AND p2.ID='Toto' AND p2.Etat='Retour' and p2.Date>p1.Date and p1.Date=(SELECT max(Date) FROM test where ID='Toto' and Etat='Absent' and Date<p2.Date)

    évidemment, il faut remplacer Toto par l'ID de la personne à chercher ^^
    1. SELECT count(*) FROM `Personne` WHERE ID='toto' AND Etat='Absent'

      la requette te renvoi le nombre de lignes ou l'id =toto et l'etat =absent

      OUPS ... mal lu la question ...

      SELECT DATE_DIFF( p2.Date, p1.Date ) FROM `Personne` as p1, `Personne` as p2 WHERE p1.ID='Toto' AND p1.Etat='Absent' AND p2.ID='Toto' AND p2.Etat='Retour'

      Pas testé !!!

      Attention, ça ne marchera pas si tu as plusieurs fois le couple Absent/Retour pour un même ID ...
      1. Heu non, ca ca te renvoit le nombre d'entrées dans la BDD, pas le nombre de jours d'absence
        faudrait faire une soustraction entre la date de retour et la date de début d'absence
        mais une même personne peut être absente plusieurs fois ? (je suppose que oui ^^)
        De même, une absence est elle toujours suivit d'un retour, ou peut-elle être suivie d'une autre absence ?
        1. Pour savoir si on peut être absent plusieurs fois, ou si 2 absences peuvent se suivre, ça, on peut pas le dire à ta place ... c'est toi qui en décide.

          Quoiqu'il en soit, pour simplifier, tu devrai décomposer en plusieurs tables ... ça permettrait des recherches plus claires et plus précises
        2. OUaaaa sa avance plein de réponce youuuuuuuouuuuuuuu

          Une absence ne peut etre suivi que d'un retour pour un ID mais il peu y avoir plussieur absence d'affilé pour des id diférent
      2. Oui j'ai vu plus tard ^^
        mais ton code marche pas s'il y a plusieurs absenses, donc ca change rien à ma question ;)
        1. Dans tous les cas, tu ne pourra pas avoir 1 seul résultat qui cumule la somme de toutes les périodes d'absence.

          A mon avis, le mieux que l'on puisse faire, c'est de renvoyer un tableau de toutes les absences. Après reste encore à les additionner ...
          1. "Dans tous les cas, tu ne pourra pas avoir 1 seul résultat qui cumule la somme de toutes les périodes d'absence. "

            jsuis pas d'accord
            là va falloir réfléchir un peu, mais à mon avis c'est tt à fait possible ^^
            1. requêtes imbriquées ...

              SELECT SUM( SELECT ...tableau des absence ) )

              En fait, le vrai problème va quand même être de récupérer la liste de toutes les absences.
              Le difficulté est de relier le retour avec l'absence précédente au sein d'une seule requête.
              Il n'est pas possible lors de l'insertion du retour de rajouter un champ précisant à quelle absence il correspond ?
              
              SELECT DATE_DIFF( p2.Date, p1.Date ) FROM `Personne` as p1, `Personne` as p2 WHERE p1.ID='Toto' AND p1.Etat='Absent' AND p2.ID='Toto' AND p2.Etat='Retour' AND p1.Date = date inférieure la plus proche de p2.Date 
              
              
              1. Un truc du genre ... peut être pas très clair ...

                SELECT SUM ( SELECT DATE_DIFF( p2.Date, p1.Date )
                    FROM `Personne` as p1, `Personne` as p2 
                    WHERE p1.ID='Toto' AND p1.Etat='Absent' AND p2.ID='Toto' AND p2.Etat='Retour' 
                        AND p1.Date = ( SELECT Date 
                                                  FROM `Personne` 
                                                  WHERE Date < p2.Date AND ID='Toto' AND Etat='Absent'
                                                  ORDER BY Date Desc 
                                                  LIMIT 1 ) )
                


                Je dois filer ...
                mais je suis curieux du résultat ...
            2. J'ai essayé rapidement, avec le peu de tests que j'ai fait ca fonctionne

              SELECT SUM( DATEDIFF(p2.Date,p1.Date))
              FROM `test` p1, `test` p2
              WHERE p1.ID='Toto' AND p1.Etat='Absent' AND p2.ID='Toto' AND p2.Etat='Retour' and p2.Date>p1.Date and p1.Date=(SELECT max(Date) FROM test where ID='Toto' and Etat='Absent' and Date<p2.Date)
              1. après petite réflexion tout à l'heure, tu peux simplifier un peu, et optimiser (toujours de tête, sans tester ...) :

                SELECT SUM( DATEDIFF(p.Date, (SELECT max(Date) FROM test WHERE ID='Toto' AND Etat='Absent' AND Date<p.Date) )) FROM `test` p WHERE p.ID='Toto' AND p.Etat='Retour'
                


                Ca évite de faire un double appel à la même table dans la requête principale.

                Petite curiosité : tu utilise quoi comme moteur sql ?
            3. Le moteur SQl est MySQL 5.0.45

              je vais essayé sa de suite et je reviens vers vous
              1. La commande ne fonctionne pas il me retourne NULL

                je vais vous ré expliqué plus clairement ce qui me gène

                La requete dois effectuer les paramètre suivant après avoir sélectionné un id et une plage de date

                je souhaiterais conaitre le nombre de jour ou mr X à été absent entre le 2009-07-01 00:00:00 jusqu'au 2009-08-01 00:00:00

                donc un affichage de l'id et du nombre de jour d'absence

                dans le cas ou Mr X est revenue le 15 à 00:00:00 je devrai voir afficher

                14 = Mr X

                cependant il ce peu que Mr X ne revienne que le 2009-08-10 00:00:00 donc je devrais voir affiché

                31 = Mr X

                sa c'est la première partie

                la seconde est celle que je désire trouvé graçe a votre aide présieuse

                c'est si Mr X est absent du 2009-08-01 00:00:00 au 2009-08-06 00:00:00 et est a nouveau absent le 2009-08-08 00:00:00 au 2009-11-01 00:00:00 et encore du 2009-08-20 00:00:00 au 2009-08-22 00:00:00
                alors je voudrais voir afficher

                5 = Mr X
                2 = Mr X
                1 = Mr X

                Est ce que cela vous à aidé à comprendre mon maudit problème
                1. A mon avis, c'est pas possible sur 1 seule requête !

                  On a vu qu'il est possible de calculer les intervalles à condition d'avoir un début et une fin.

                  Là, tu demande les intervalles contenus dans une période précise, avec en plus le souhait d'avoir les parcelles d'intervalles et début ou en fin de période (donc, coupé au milieu).

                  Il faudrait faire en plusieurs étapes (a voir comment l'intégrer en sql)
                  1 - récupérer les absences entières
                  2 - tester si il y a une absence en cours le premier jour -> définir le nombre de jours qu'il reste
                  3 - tester si il y a une absence en cours le dernier jour -> définir le nombre de jours déjà écoulés
                  4 - additionner le tout
              2. Merci ça fonctionne bien

                voici ma commande grâce à vous

                SELECT p1.site, p1.date AS Absent, p2.date AS Retour, TIMEDIFF( p2.date, p1.`date` ) AS duree
                FROM etat p1,etat p2
                WHERE p1.site LIKE '%H%'
                AND p1.site = p2.site
                AND p1.etat LIKE 'Absent'
                AND p2.site LIKE '%H%'
                AND p2.etat = 'Retour'
                AND p2.date > p1.date
                AND p1.date = (
                SELECT max( p.date )
                FROM etatp
                WHERE site LIKE '%H%'
                AND etat = 'Absent'
                AND p.date < p2.date )
                AND p1.date
                BETWEEN '2009-06-01 00:00:00'
                AND '2009-07-31 00:00:00'
                AND p2.date
                BETWEEN '2009-06-01 00:00:00'
                AND '2009-07-31 00:00:00'
                ORDER BY p1.site, duree