IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes et SQL. Discussion :

Calculs sur intervalles de dates [AC-2010]


Sujet :

Requêtes et SQL.

  1. #1
    Membre averti Avatar de archonte
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    342
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 342
    Points : 394
    Points
    394
    Par défaut Calculs sur intervalles de dates
    Bonjour à Tous,

    Je dispose des tables ou vues suivantes :
    - Base : ma table de données, non modifiable, issue d'un autre logiciel
    - ReqSejours : une vue : sélectionne à partir de Base l'identifiant client unique (ID) et les dates de début (Debut) et de fin (Fin) de leur séjour
    - Calendrier : une vue : comporte une série de date (Jours) (en pratique : série chronologique complète du 1er/01/2011 au 26/10/2013)

    L'objectif :
    Obtenir une vue comportant le nombre de séjours "en cours" pour chaque date du Calendrier.

    Ma proposition :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /* Récupérer le nombre de séjours pour lesquels la date testée est comprise entre les dates de début et de fin du séjour */
    SELECT Calendrier.Jours, Count(ReqSejours.ID) AS NbSejours
     
    FROM ReqSejours, Calendrier
     
    WHERE 
      (ReqSejours.Debut <= Calendrier.Jours)
      AND 
      (ReqSejours.Fin >= Calendrier.Jours)
     
    GROUP BY Calendrier.Jours
     
    ORDER BY Calendrier.Jours;

    Mon problème :
    Sur 1029 lignes de résultat, j'ai 28 lignes avec des résultats aberrants (valeurs doubles de la valeur réelle); que j'ai contrôlé avec la requête manuelle suivante, qui, elle, donne des résultats corrects :

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    PARAMETERS [date] DateTime;
    SELECT Count(ReqSejours.ID) AS NbSejours
    FROM ReqSejours
    WHERE 
      (ReqSejours.Debut <= [date]) 
      AND 
      (ReqSejours.Fin >= [date]);

    Ma Question :
    Étant béotien en SQL, quelqu'un peut-il m'expliquer pourquoi j'obtiens ces résultats discordants; et comment corriger mon code ? sachant qu'il n'y a pas de trous ni de valeur null dans la vue ReqSejours.
    Merci d'avance.

  2. #2
    Membre éclairé
    Homme Profil pro
    D.E.
    Inscrit en
    Octobre 2013
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : D.E.

    Informations forums :
    Inscription : Octobre 2013
    Messages : 562
    Points : 764
    Points
    764
    Par défaut
    Citation Envoyé par archonte Voir le message
    FROM ReqSejours, Calendrier

    FROM ReqSejours
    Le probléme dans votre proposition est un problème de jointure. Vous utilisez deux entités (ReqSejours, Calendrier), il faudrait indiquer la jointure entre les deux sauf que si vous le faites, sur la date de début, par exemple, cela restreindra les enregistrements à cette date, donc cela ne donnera pas ce que vous voulez.

    Si vous regardez dans la seconde solution, il n'y a qu'une entité ReqSejours donc pas de problème pour "requeter".

  3. #3
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 884
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 884
    Points : 58 499
    Points
    58 499
    Billets dans le blog
    45
    Par défaut
    bonsoir,

    la requête me semble pourtant correcte et devrait, pour chaque date du calendrier, retourner le nombre de séjours en cours.
    En fait la jointure est située dans le WHERE, on peut rendre l'écriture plus sympathique avec :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    ...WHERE Calendrier.jours between Debut AND Fin

    Si la requête "manuelle" retourne le bon résultat, l'explication vient sans doute du côté de la table Calendrier. Un trou dans le calendrier, des dates mal encodées, pb de format...

    C'est possible de reconstituer le problème dans une base simplifiée en pièce-jointe ?

  4. #4
    Membre averti Avatar de archonte
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    342
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 342
    Points : 394
    Points
    394
    Par défaut
    Merci f-leb pour ta réponse,

    1/ bien sûr que le between est plus sympathique, mais en fait, j'ai laissé les 2 conditions séparées qui me permettent alors de tester avec et sans inclusion des bornes de l'intervalle :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ...
    WHERE 
      /* cas n°1 */
      (ReqSejours.Debut <= Calendrier.Jours)
      AND 
      (ReqSejours.Fin >= Calendrier.Jours)
      /* ou : */
      /* cas n°2 */
      (ReqSejours.Debut < Calendrier.Jours)
      AND 
      (ReqSejours.Fin > Calendrier.Jours)
    ....

    2/ je comprends mal pourquoi sur la même table, la requête "manuelle" fonctionne mais pas la requête avec jointure ... D'ailleurs l'ensemble des autres lignes de résultat donne des valeurs correctes (c'-à-d < 50). J'ai l'impression que toutes les dates sont correctement encodées.

    Je mets en PJ un extrait de la table; les dates à problème sont :
    03-mars-11
    01-mars-12
    02-mars-12
    02-mars-11
    01-mars-11
    01-juil-11
    01-mai-11
    01-déc-11
    01-déc-12
    01-mars-13
    02-mars-13
    03-mars-13
    01-oct-12
    01-mai-13
    01-oct-13
    01-mai-12
    01-oct-11
    Merci,
    Fichiers attachés Fichiers attachés

  5. #5
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    12 884
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 12 884
    Points : 58 499
    Points
    58 499
    Billets dans le blog
    45
    Par défaut
    bonjour,

    J'ai testé ta vue ReqSejours avec une table Calendrier que j'ai générée vite fait avec Excel, et je n'ai pas les erreurs que tu rencontres

    comme je le disais :
    Citation Envoyé par f-leb Voir le message
    ... l'explication vient sans doute du côté de la table Calendrier.
    Comment est générée cette table/requête ? Un copier/coller d'Excel ?

    Je poste mon fichier de test à tout hasard...
    Fichiers attachés Fichiers attachés

  6. #6
    Membre averti Avatar de archonte
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    342
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 342
    Points : 394
    Points
    394
    Par défaut
    Bonjour !

    Citation Envoyé par f-leb Voir le message
    .... l'explication vient sans doute du côté de la table Calendrier
    OUI (3 fois OUI ) : l'explication vient de la table calendrier

    Citation Envoyé par f-leb Voir le message
    Comment est générée cette table/requête ? Un copier/coller d'Excel ?
    Malheureusement non ....
    Je m'étais servi d'une requête trouvée sur ce forum :
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DATESERIAL(2011+ID1,ID2+1,ID3+1) AS Jours
    FROM (SELECT TOP 5 (SELECT Count(ID) as a FROM MSysObjects TA WHERE TA.ID<TA1.ID) AS ID1 FROM MSysObjects AS TA1 ORDER BY ID)  AS T1, (SELECT TOP 12 (SELECT Count(ID)  FROM MSysObjects TA WHERE TA.ID<TA1.ID) AS ID2 FROM MSysObjects AS TA1 ORDER BY ID)  AS T2, (SELECT TOP 31 (SELECT Count(ID)  FROM MSysObjects TA WHERE TA.ID<TA1.ID) AS ID3 FROM MSysObjects AS TA1 ORDER BY ID)  AS T3
    WHERE DATESERIAL(2011+ID1,ID2,ID3)<=date()
    ORDER BY DATESERIAL(2011+ID1,ID2,ID3);

    Effectivement, en utilisant la solution simple (= générer la liste sur excel, puis l'exporter), je trouve aussi des résultats adaptés !!!

    Merci pour l'aide


    je me pencherais plus tard sur la différence entre les deux tables ... et sur cette requête de génération d'une série de dates ...

    cordialement,


+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2007] Calcule sur intervalle
    Par Loganchab dans le forum Excel
    Réponses: 1
    Dernier message: 17/06/2014, 19h24
  2. Boucle incrémentation sur intervalle de dates
    Par clickandgo dans le forum VBA Access
    Réponses: 6
    Dernier message: 10/06/2013, 19h27
  3. MDX: Cumul sur intervalle de date
    Par faulk dans le forum SSAS
    Réponses: 5
    Dernier message: 19/01/2012, 18h10
  4. ouvrir form sur intervalle de date
    Par krassi dans le forum IHM
    Réponses: 4
    Dernier message: 22/02/2007, 17h19
  5. calculer un intervalle de dates
    Par vodevil dans le forum Modules
    Réponses: 3
    Dernier message: 16/01/2006, 21h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo