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

SQL Firebird Discussion :

Construction d'une requête imbriquée


Sujet :

SQL Firebird

  1. #1
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut Construction d'une requête imbriquée
    Bonjour à tous, j'ai un problème de réflexion: j'ai des soucis pour faire une requête .

    Je suis sous Firebird et j'ai une table qui contient les champs d'occupation.
    dateDebutOccupation, duree, Emplacement, Occupation (m²)...


    Je vous explique la situation: je gère des occupations de surfaces, le but de ma requete serait d'avoir l'occupation totale à une date donnée puis ensuite entre 2 dates.
    J'ai fait un petit dessin pour être clair:


    les flèches vertes sont les occupations (avec la surface occupée), A et B sont les dates qui définissent l'intervalle de temps, p1 à p6 sont les dates où l'occupation totale doit être calculée.
    Mon idée est que pour avoir la surface maximale occupée entre les dates A et B, il faut que je fasse la somme des occupations de chacune des dates p1 à p6 + celles de A et B et prendre la somme la plus grande. J'ai déja les requetes pour ne sélectionner que les dates entre A et B mais je ne vois pas comment mixer le tout pour avoir ma selection du max de mes sommes.
    J'espere que tout est clair , voilà mes 2 requetes en omettant l'emplacement:
    Code :
    SELECT dateDebutOccupation FROM Occupations WHERE dateDebutOccupation >=A ANDdateDebutOccupation <B

    Code :
    SELECT (dateDebutOccupation+duree) FROM Occupations WHERE (dateDebutOccupation+duree)>A AND(dateDebutOccupation+duree)<B


    Voilà si vous avez des questions ou des idées... toute aide est la bienvenue car je suis pas loin de la pendaison
    Merci

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 99
    Points : 110
    Points
    110
    Par défaut
    Bonjour,

    Je ne comprend pas bien tes requêtes par rapport à ce que tu cherche...

    Occupation totale à une date donnée :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Select
          somme(Occupation)
      from
          Occupations
      where
          dateDebutOccupation <= date_donnee
          and dateDebutOccupation + duree >= date_donnee
    Une petite question concernant l'occupation entre 2 dates, faut il ne considérer que les occupations qui sont entièrement contenues entre les 2 dates ou bien il faut aussi comptabiliser les occupations qui sont à chevale sur l'une ou l'autre ou les deux dates ?

  3. #3
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    La requête que tu as ecrit est celle pour une date donnée. Elle correspond a celle que j'ai hormis un >=.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Select somme(Occupation) from Occupations where dateDebutOccupation <= date_donnee and dateDebutOccupation + duree > date_donnee
    Les 2 requêtes que j'ai ecrite donnent les dates ou il y a un changement d'occupation entre les 2 dates. En faisant un UNION, j'obtient donc l'ensemble des dates où il faut faire les sommes d'occupation. Il faut aussi faire la somme d'occupation pour les 2 dates A et B. On obtient donc l'occupation pour les dates A, p1, p2, p3, p4, p5, p6, B. Il ne reste plus qu'a remonter le max de ces occupations.
    L'exercice étant d'arriver à faire l'ensemble en une seule requête .

  4. #4
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    La requête qui remonte les dates retourne p1 à p6.
    la requête qui donne l'occupation doit remonter l'ensemble des enregistrements:
    A: 250 m²
    p1: 200 m²
    p2: 300 m²
    p3: 250 m²
    p4: 150 m²
    p5: 180 m²
    p6: 100 m²
    B: 100 m²

    l'occupation à la date B n'est pas nécessaire car elle correspond à l'occuption p6.

    il faut que la requête me remonte 300 m².

  5. #5
    Inactif   Avatar de Médiat
    Inscrit en
    Décembre 2003
    Messages
    1 946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2003
    Messages : 1 946
    Points : 2 227
    Points
    2 227
    Par défaut
    La requête ci-dessous est testée sous ORACLE :

    Date de début = 15/01/2005
    Date de Fin = 10/06/2005

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    select max(sum(Occupation))
    from dvp_Occupation inner join (select dateDebutOccupation as Borne
                                    from  dvp_occupation
                                    where dateDebutOccupation >= to_date('15/01/2005', 'DD/MM/YYYY')
                                      and dateDebutOccupation  < to_date('10/06/2005', 'DD/MM/YYYY')
                                 union
                                    select dateDebutOccupation+duree
                                    from  dvp_occupation
                                    where dateDebutOccupation + duree >= to_date('15/01/2005', 'DD/MM/YYYY')
                                      and dateDebutOccupation + duree < to_date('10/06/2005', 'DD/MM/YYYY')
                                 union
                                    select to_date('15/01/2005', 'DD/MM/YYYY')
                                    from dual) a
                              on  dateDebutOccupation <= Borne
                              and dateDebutOccupation + Duree > Borne
    group by Borne;
    to_date est facile à comprendre et à transcrire si nécessaire ; le select to_date('15/01/2005', 'DD/MM/YYYY') from dual permet d'ajouter la ligne avec la date de départ, il doit y avoir l'équivalent avec FireBird, sinon il faut ajouter une union, tiens-moi au courant...
    J'affirme péremptoirement que toute affirmation péremptoire est fausse
    5ième élément : barde-prince des figures de style, duc de la synecdoque
    Je ne réponds jamais aux questions techniques par MP

  6. #6
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    Merci de vous être penché sur la question je vais tester sous firebird. Je ne suis pas sûr qu'il accepte une sous-requête dans un inner join, je vous tiens au courant.

  7. #7
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    FireBird 1.5.3 n'accepte pas le select dans la clause from . (Erreur de syntax)
    Y a-t-il un moyen de faire passer le prédicat dans la clause where ?

    On est pas loin. Il faut aussi que je regarde un équivalent à from dual.

  8. #8
    Membre expert
    Avatar de Alexandre T
    Homme Profil pro
    Chef de projets AMO
    Inscrit en
    Mai 2002
    Messages
    1 213
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Chef de projets AMO
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2002
    Messages : 1 213
    Points : 3 001
    Points
    3 001
    Par défaut
    En même temps, si vous postiez dans le forum Firebird, vous auriez plus de réponses !

    Je déplace.
    Alexandre Tranchant
    Chef de projet AMO pour le Cerema.
    Retrouvez mes articles sur PHP et Symfony

  9. #9
    Membre actif Avatar de TMuet
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Septembre 2003
    Messages
    225
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2003
    Messages : 225
    Points : 288
    Points
    288
    Par défaut
    Citation Envoyé par gudul
    Il faut aussi que je regarde un équivalent à from dual.
    from rdb$database

  10. #10
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    merci, je me doutais bien que c'était rdb$database.

    Est il possible de mettre un select dans la clause "from" ?
    si non, la version firebird 2.0 corrige-t-elle ce manque ?

    comment pouvoir réecrire la requête faite sous Oracle afin qu'elle fonctionne sous firebird?

  11. #11
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par gudul
    merci, je me doutais bien que c'était rdb$database.
    si non, la version firebird 2.0 corrige-t-elle ce manque ?
    oui
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  12. #12
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par gudul
    comment pouvoir réecrire la requête faite sous Oracle afin qu'elle fonctionne sous firebird?
    C'est possible avec si tu crée une procédure stockée
    vite fait comme ça tu fait une procédure stockée qui ramène les bornes (en fait l'équivalent du select qui est dans le from dans la version oracle
    puis ensuite tu fait ta requête qui ramène ta surface

    ce qui donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    SET TERM ^^ ;
    CREATE PROCEDURE P_OCCUPATIONS (
      DEBUT Date,
      FIN Date)
     returns (
      BORNE Date) AS
    begin
      FOR SELECT CAST(dateDebutOccupation AS DATE) FROM TB_Occupations
          WHERE dateDebutOccupation >=:DEBUT
          AND dateDebutOccupation <:FIN
          UNION
          SELECT CAST((dateDebutOccupation+duree) AS DATE)
          FROM TB_Occupations WHERE CAST((dateDebutOccupation+duree) AS DATE)>:DEBUT
          AND CAST((dateDebutOccupation+duree) AS DATE)<:FIN
          INTO :BORNE
       DO
       SUSPEND;
    end^^
    SET TERM ; ^^
    ensuite tu utilises la procédure comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT FIRST 1 sum(Occupation)
     FROM TB_OCCUPATIONS INNER JOIN
      P_OCCUPATIONS ('01/15/2005','06/10/2005') on  dateDebutOccupation <= Borne
      and dateDebutOccupation + Duree > Borne
    group by Borne
    ORDER BY 1 DESC;
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  13. #13
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    merci, j'essai ca tout de suite et je vous tiens au courant

  14. #14
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    apres installation de firebird2, la requete faite sur le modèle d'oracle fonctionne sauf le max.
    (Invalid token.
    Dynamic SQL Error.
    SQL error code = -104.
    Nested aggregate functions are not allowed.)

    la requête utilisant le procedure stockée fonctionne aussi. je n'ai pas l'occupation pour la date de début et le max ne passe pas non plus.

  15. #15
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par gudul
    apres installation de firebird2, la requete faite sur le modèle d'oracle fonctionne sauf le max.
    (Invalid token.
    Dynamic SQL Error.
    SQL error code = -104.
    Nested aggregate functions are not allowed.)

    la requête utilisant le procedure stockée fonctionne aussi. je n'ai pas l'occupation pour la date de début et le max ne passe pas non plus.
    avec FIRST 1 et ORDER BY ... DESC, pas besoin du max
    et s'il te manque la date du début, modifie la procédure stockée pour l'inclure, je l'ai fait vite fait sur le gaz, mais tu as là tous les éléments necessaires.
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

  16. #16
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    Merci pour tout. cela fonctionne très bien.

  17. #17
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    J'ai encore un problème . La requête ne me remonte pas la date et l'occupation quand celle ci est à 0.

    La procédure stoquée me remonte bien les dates où il y a un changement d'occupation, dont la dernière date ou l'occupation passe à 0 mais dans la requête, je n'ai pas la date d'occupation avec une surface à null. (j'ai mis un right outer join sans grand succes)


  18. #18
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    oups je me suis trompé de requête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT BORNE, occupsurface.f_occupoccupsurface
    FROM occupsurface RIGHT OUTER JOIN
      P_OCCUPATIONS ('01/25/2007','02/28/2007') on  occupsurface.d_dateoccupsurface <= Borne
      and occupsurface.d_dateoccupsurface + occupsurface.f_dureeoccupsurface > Borne
    group by Borne
    voici la procedure qui me revoit ce qu'il faut.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    SET TERM ^ ;
     
    CREATE PROCEDURE P_OCCUPATIONS (
        DEBUT DATE,
        FIN DATE
    RETURNS (
        BORNE DATE)
    AS
    begin
      SELECT :debut FROM rdb$database INTO :borne;
      SUSPEND;
     
      FOR SELECT CAST(occupsurface.d_dateoccupsurface AS DATE) FROM occupsurface
          WHERE occupsurface.d_dateoccupsurface >:DEBUT
            AND occupsurface.d_dateoccupsurface <:FIN
          UNION
          SELECT CAST((occupsurface.d_dateoccupsurface + occupsurface.f_dureeoccupsurface) AS DATE)
          FROM occupsurface WHERE CAST((occupsurface.d_dateoccupsurface + occupsurface.f_dureeoccupsurface) AS DATE)>:DEBUT
            AND CAST((occupsurface.d_dateoccupsurface + occupsurface.f_dureeoccupsurface) AS DATE)<:FIN
          INTO :BORNE
       DO
       SUSPEND;
    end^
     
    SET TERM ; ^

  19. #19
    Membre régulier
    Profil pro
    Ingenieur developpement
    Inscrit en
    Septembre 2002
    Messages
    173
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Ingenieur developpement

    Informations forums :
    Inscription : Septembre 2002
    Messages : 173
    Points : 104
    Points
    104
    Par défaut
    J'ai trouvé une solution de secours avec vos réponses. En fait je fais une requête qui me ramène toutes les dates pertinentes puis pour chaque date je vais chercher en base l'occupation. Pas top pour l'accès au SGBD mais comme le serveur et l'application sont sur la même machine, ça tient la route pour le moment.

    à tous.



    P.S: Je mets pas le sujet en résolu car je cherche encore quelques suggestions. Je repasserais régulièrement.

  20. #20
    Membre expert

    Homme Profil pro
    Consultant spécialité Firebird
    Inscrit en
    Mai 2002
    Messages
    2 342
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France

    Informations professionnelles :
    Activité : Consultant spécialité Firebird
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 342
    Points : 3 712
    Points
    3 712
    Par défaut
    Citation Envoyé par gudul
    J'ai encore un problème . La requête ne me remonte pas la date et l'occupation quand celle ci est à 0.

    La procédure stoquée me remonte bien les dates où il y a un changement d'occupation, dont la dernière date ou l'occupation passe à 0 mais dans la requête, je n'ai pas la date d'occupation avec une surface à null. (j'ai mis un right outer join sans grand succes)
    en quoi tu as besoin de ces infos ?
    je n'en vois pas l'intérêt au vu de ta demande
    Philippe Makowski
    IBPhoenix - Firebird
    Membre de l'April

Discussions similaires

  1. Construction d'une requête "imbriquée" avec Oracle
    Par kyra78 dans le forum Langage SQL
    Réponses: 0
    Dernier message: 05/02/2008, 14h29
  2. une requête imbriquée est-elle autorisée dans un INSERT ???
    Par Ekimasu dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 04/08/2005, 09h21
  3. Passage de paramètres dans une requête imbriquée
    Par DrakkoFR dans le forum Langage SQL
    Réponses: 2
    Dernier message: 07/02/2005, 12h46
  4. [Requête] Faire une requête imbriquée?
    Par sekiryou dans le forum Requêtes
    Réponses: 2
    Dernier message: 17/01/2004, 22h52
  5. problème avec une requête imbriquée
    Par jaimepasteevy dans le forum Langage SQL
    Réponses: 13
    Dernier message: 05/12/2003, 10h29

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