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

Langage SQL Discussion :

[Sql] Filtre sur créneau horraire


Sujet :

Langage SQL

  1. #1
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut [Sql] Filtre sur créneau horraire
    Bonjour,

    Je cherche à faire un filtre sur une table qui contient des créneaux horraires qui me permettrait de vérifier si le nouveau créneau que je souhaite créer est dans une plage libre.

    Ma table ressemble un peu à cela:
    Jour 1 | Creneau 1 | 09:00 | 09:30
    Jour 1 | Creneau 2 | 10:00 | 11:00
    Jour 1 | Creneau 3 | 11:00 | 12:00
    ......

    Donc mon filtre doit pouvoir me dire :
    que le créneau 08:00 | 09:40 n'est pas possible
    que le créneau 09:40 | 10:00 est possible
    que le creneau 08:00 | 09:10 n'est pas possible
    que le créneau 09:40 | 10:30 n'est pas possible

    quelqu' un a t'il une idée ?

    Merci

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579

  3. #3
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut
    Merci

    par contre le prédicat OVERLAPS ne semble par fonctionner sous Oracle.

  4. #4
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    La fonction OVERLAPS est traduite en français dans l'article. Vous pouvez l'exprimer avec une combinaisons de conditions simples ou même vous faire ça en fonction utilisateur.

  5. #5
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut
    Merci pour le tuto , il est très intéressant.

    J'ai repris la requete:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT *
    FROM   PERIODE
    WHERE  (P1_DEBUT > P2_DEBUT AND (P1_DEBUT < P2_FIN OR P1_FIN < P2_FIN)) OR
           (P2_DEBUT > P1_DEBUT AND (P2_DEBUT < P1_FIN OR P2_FIN < P1_FIN)) OR
           (P1_DEBUT = P2_DEBUT AND (P1_FIN IS NOT NULL AND P2_FIN IS NOT NULL))
    j'ai juste un soucis lorsque P1_Debut et P1_Fin chevauche intégralement P2_Debut et P2_Fin

    exemple ; j'ai dans ma table un créneau 10:00 - 10:45 -> je teste 10:00 - 10:45 la requete me renvoie:

    10:00-10:45
    10:00-10:45
    10:00-11:00
    10:00-11:00

    quelqu'un peut il m'aider ?

    Merci

  6. #6
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Je crois qu'il y a une petite coquille dans cette transcription du prédicat overlaps.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    (P1_DEBUT > P2_DEBUT AND (P1_DEBUT < P2_FIN OR P1_FIN < P2_FIN)) OR
    (P2_DEBUT > P1_DEBUT AND (P2_DEBUT < P1_FIN OR P2_FIN < P1_FIN)) OR
    (P1_DEBUT = P2_DEBUT AND (P1_FIN IS NOT NULL AND P2_FIN IS NOT NULL))
    Essayez cette formulation et dîtes moi si ça corrige le problème et réagit correctement dans tous les cas.

  7. #7
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut
    Merci.

    Cela ne corrige en rien. Cependant je ne vois pas de difference de code avec l'ancienne version.

  8. #8
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Oui pardon, j'ai pris cette expression dans un fichier que j'avais gardé mais c'est la même bonne version.

    Par contre montrez votre jeu d'essai, votre requête et le résultat attendu car ça ne devrait pas poser problème.

  9. #9
    Membre confirmé Avatar de miloux32
    Profil pro
    Inscrit en
    Juillet 2003
    Messages
    545
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2003
    Messages : 545
    Points : 565
    Points
    565
    Par défaut
    Citation Envoyé par beegood Voir le message
    Merci pour le tuto , il est très intéressant.

    J'ai repris la requete:

    SELECT *
    FROM PERIODE
    WHERE (P1_DEBUT > P2_DEBUT AND (P1_DEBUT < P2_FIN OR P1_FIN < P2_FIN)) OR
    (P2_DEBUT > P1_DEBUT AND (P2_DEBUT < P1_FIN OR P2_FIN < P1_FIN)) OR
    (P1_DEBUT = P2_DEBUT AND (P1_FIN IS NOT NULL AND P2_FIN IS NOT NULL))

    j'ai juste un soucis lorsque P1_Debut et P1_Fin chevauche intégralement P2_Debut et P2_Fin

    exemple ; j'ai dans ma table un créneau 10:00 - 10:45 -> je teste 10:00 - 10:45 la requete me renvoie:

    10:00-10:45
    10:00-10:45
    10:00-11:00
    10:00-11:00

    quelqu'un peut il m'aider ?

    Merci
    Remplace les > par >= et < par <=

  10. #10
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Citation Envoyé par miloux32 Voir le message
    Remplace les > par >= et < par <=
    Surtout pas !!!

  11. #11
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Je viens de voir le jeu d'essai dans votre premier post

    Le prédicat OVERLAPS indique qu'une periode chevauche une autre période. Pour avoir les plage libres, vous devez utilisez la négation du prédicat. Est ce que c'est bien ce que vous faîtes ?

  12. #12
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut
    Mon jeu d'essai :

    J'ai en table :
    09:00-09:45
    10:00-10:45
    11:00-11:45
    12:00-12:45

    Ma requete :
    Select CRENEAU_HDEBUT as hDebut,
    CRENEAU_HFIN as hFin
    From ENT_CRENEAUH
    Where CRENEAU_IDSESSION=ID_SESSION
    and CRENEAU_IDJURY=ID_JURY
    and to_char(CRENEAU_DATE,'dd fmmonth yyyy')=lower(DATE_JURY)
    and (CRENEAU_HDEBUT > P2_DEBUT AND (CRENEAU_HDEBUT < P2_FIN OR CRENEAU_HFIN < P2_FIN)) OR
    (P2_DEBUT > CRENEAU_HDEBUT AND (P2_DEBUT < CRENEAU_HFIN OR P2_FIN < CRENEAU_HFIN)) OR
    (CRENEAU_HDEBUT = P2_DEBUT AND (CRENEAU_HFIN IS NOT NULL AND P2_FIN IS NOT NULL));
    (C'est un extrait)

    J'appelle ma fonction (oracle en pl/sql) :
    select isCreneauLibre(7,1,'01 mai 2008','10:00','10:45') from dual;

    cela devrait me renvoyer :10:00 - 10:45

    mais j'ai en resultat:

    10:00-10:45
    10:00-10:45
    10:00-11:00
    10:00-11:00

  13. #13
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Voir mon post juste au dessus.

  14. #14
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut
    Je cherche bien à vérifier si mon créneau n'est pas déjà occupé. C'est le résultat de la requete qui me pertube un peu. C'est vrai que le resultat m'indique que mon créneau est occupé cela me renvoi quelques choses.

    seulement la requete me renvoi 2* 10:00 -10:45 et 2* 10:00 - 11:00
    alors qu'en théorie elle devrait me dire juste : 10:00-10:45

  15. #15
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Si vous avez en table :

    09:00-09:45
    10:00-10:45
    11:00-11:45
    12:00-12:45

    et que grosso modo vous faites ::

    SELECT ...
    FROM ENT_CRENEAUH
    ...

    Il est impossible que vous ayez 2 fois ces plages dans le résultat alors qu'elles ne sont qu'une fois dans la table. Vous devez faire une autre requête que celle que vous montrez.

  16. #16
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut
    Voici le code exacte, c'est une fonction pl/sql :

    Create or replace function isCreneauLibre(ID_SESSION NUMBER,
    ID_JURY NUMBER,
    DATE_JURY varchar2,
    P2_DEBUT varchar2,
    P2_FIN varchar2) return number
    IS

    /* Variables */
    isLibre NUMBER(1);
    nombreCreneau NUMBER(10);
    hDebut VARCHAR2(5);
    hFin VARCHAR2(5);

    /* Curseur */
    CURSOR curCreneau IS

    Select CRENEAU_HDEBUT as hDebut,
    CRENEAU_HFIN as hFin
    From ENT_CRENEAUH
    Where CRENEAU_IDSESSION=ID_SESSION
    and CRENEAU_IDJURY=ID_JURY
    and to_char(CRENEAU_DATE,'dd fmmonth yyyy')=lower(DATE_JURY)
    and (CRENEAU_HDEBUT > P2_DEBUT AND (CRENEAU_HDEBUT < P2_FIN OR CRENEAU_HFIN < P2_FIN)) OR
    (P2_DEBUT > CRENEAU_HDEBUT AND (P2_DEBUT < CRENEAU_HFIN OR P2_FIN < CRENEAU_HFIN)) OR
    (CRENEAU_HDEBUT = P2_DEBUT AND (CRENEAU_HFIN IS NOT NULL AND P2_FIN IS NOT NULL));

    /* Corps */
    Begin

    OPEN curCreneau;

    LOOP
    FETCH curCreneau INTO hDebut,hFin;
    EXIT WHEN curCreneau%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(hDebut||'-'||hFin);

    END LOOP;

    CLOSE curCreneau;

    RETURN 1;
    End;
    /
    Je l'appelle comme suit :
    select isCreneauLibre(7,1,'01 mai 2008','10:46','10:50') from dual;

    Si je retire le filtre de test de chevauchements (le dernier and) :
    j'ai comme resultats:
    12:00-12:45
    11:00-11:45
    09:00-09:45
    10:00-10:45

    soit l'ensemble de mes créneaux en base.

    Merci

  17. #17
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut
    si je fais :

    Select CRENEAU_HDEBUT as hDebut,
    CRENEAU_HFIN as hFin
    From ENT_CRENEAUH
    Where CRENEAU_IDSESSION=7
    and CRENEAU_IDJURY=1
    and to_char(CRENEAU_DATE,'dd fmmonth yyyy')=lower('01 mai 2008')
    and (CRENEAU_HDEBUT > '07:45' AND (CRENEAU_HDEBUT < '08:45' OR CRENEAU_HFIN < '08:45')) OR
    ('07:45' > CRENEAU_HDEBUT AND ('07:45' < CRENEAU_HFIN OR '08:45' < CRENEAU_HFIN)) OR
    (CRENEAU_HDEBUT = '07:45' AND (CRENEAU_HFIN IS NOT NULL AND '08:45' IS NOT NULL));
    cela me renvoi : 07:00 - 08:00

    Or je n'ai pas de créneau entre 07:00 et 08:00 , je ne comprend plus rien.

  18. #18
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Virez moi cette procédure stockée.
    Partez sur un jeu d'essai très réduit dans votre table de test.
    Testez la requête directement avec différentes valeurs en dur.

    SQL n'invente pas des tuples qui ne sont pas présents dans la table de départ.

  19. #19
    Membre éprouvé Avatar de shaun_the_sheep
    Homme Profil pro
    Chef de projet NTIC
    Inscrit en
    Octobre 2004
    Messages
    1 619
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Chef de projet NTIC
    Secteur : Enseignement

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 619
    Points : 996
    Points
    996
    Par défaut
    Merci pour l'idée.

    J'ai réduit mon jeu d'essai (j'avais d'autres créneaux pour d'autre journée). Cela me renvoyé bien ce qu'il fallait.

    J'ai ajouté d'autres creneaux sur une autre journée. La j'avais des créneaux fantomes.

    j'ai donc revu ma requete soit:
    Select CRENEAU_HDEBUT as hDebut,
    CRENEAU_HFIN as hFin
    From ENT_CRENEAUH
    Where CRENEAU_IDSESSION=ID_SESSION
    and CRENEAU_IDJURY=ID_JURY
    and to_char(CRENEAU_DATE,'dd fmmonth yyyy')=lower(DATE_JURY)
    and ((CRENEAU_HDEBUT > P2_DEBUT AND (CRENEAU_HDEBUT < P2_FIN OR CRENEAU_HFIN < P2_FIN)) OR
    (P2_DEBUT > CRENEAU_HDEBUT AND (P2_DEBUT < CRENEAU_HFIN OR P2_FIN < CRENEAU_HFIN)) OR
    (CRENEAU_HDEBUT = P2_DEBUT AND (CRENEAU_HFIN IS NOT NULL AND P2_FIN IS NOT NULL)));
    c'est tout.

  20. #20
    Membre émérite

    Profil pro
    Inscrit en
    Mars 2005
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mars 2005
    Messages : 1 683
    Points : 2 579
    Points
    2 579
    Par défaut
    Très bien.

    Attention à vos types de données aussi. Vous utilisez du varchar au lieu d'un type date ce que je ne conseillerais pas.

    Quand vous manipulez un type date avec des opérateurs de comparaison, vous êtes sûrs d'avoir une date complète. L'utilisation de varchar ou de colonne ne stockant que l'heure est dangereux à l'utilisation.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [AC-2007] Filtre sur une requête SQL
    Par rch05 dans le forum Requêtes et SQL.
    Réponses: 19
    Dernier message: 01/08/2011, 14h25
  2. Réponses: 4
    Dernier message: 04/02/2008, 19h09
  3. [SQL - Oracle 9i] Requete Sql avec filtre sur critere
    Par shaun_the_sheep dans le forum Oracle
    Réponses: 3
    Dernier message: 05/12/2007, 09h45
  4. filtre sur requete SQL
    Par profane dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 20/06/2007, 12h57
  5. [SQL Server] Filtré sur une table avant une jointure externe
    Par TangoZoulou dans le forum Langage SQL
    Réponses: 2
    Dernier message: 06/11/2006, 16h52

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