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 Oracle Discussion :

Gérer une condition. Besoin de PL/SQL ou juste SQL ?


Sujet :

SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Décembre 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 73
    Par défaut Gérer une condition. Besoin de PL/SQL ou juste SQL ?
    Bonjour.

    Sous Oracle, je dispose de 4 tables :
    -commande, avec 'id_commande' pour la clé primaire
    -brulage, avec 'tc_typecontrat', 'id_offre' et 'id_commande' pour les clés primaires
    -offre, avec 'tc_typecontrat', 'id_offre' et 'id_commande' pour les clés primaires
    -compte, avec 'id_dossier' pour la clé primaire

    Je dois écrire une requête qui permette d'identifier, si elle existe, une offre "PRE" active sur le dossier sur lequel la commande a été réalisée, sinon une offre "POST" et compléter par le code du dossier.

    Dois-je passer par le PL/SQL d'Oracle pour traiter cette condition "Si...Sinon" ?
    Si oui, pourriez-vous, s'il vous plaît, m'indiquer comment faire ?

    Séparément chacune de ces conditions se traiterait comme cela :
    Pour qu'une offre "PRE" soit active sur le dossier d'une commande, il faut que le champ datefin de la table offre ne soit pas nul, ce qui donne la requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select offre.id_offre from offre, commande where offre.tc_typecontrat = 'PRE' and offre.datefin is not null and offre.id_dossier = commande.id_dossier
    Pour que ce soit une offre "POST", c’est la même requête mais avec offre.tc_typecontrat = 'POST' et en rajoutant compte.code à la clause select.

  2. #2
    Membre émérite Avatar de NicoL__
    Homme Profil pro
    Architecte
    Inscrit en
    Janvier 2011
    Messages
    399
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte

    Informations forums :
    Inscription : Janvier 2011
    Messages : 399
    Par défaut
    Je ne pense pas avoir suivi toute la subtilité de ta demande mais voila quelque chose de pas fin : union entre les deux type de résultat possible PRE et POST, un colonne pour les trier (PRE en premier) et je prends la 1er ligne.
    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
     
     
    select * from (select * from (
    SELECT offre.id_offre, null as code, 1 as MONTRI
    FROM offre, commande 
    WHERE offre.tc_typecontrat = 'PRE' 
    AND offre.datefin IS NOT NULL 
    AND offre.id_dossier = commande.id_dossier
    union all
    SELECT offre.id_offre, compte.code, 2 as MONTRI
    FROM offre, commande, compte 
    WHERE offre.tc_typecontrat = 'POST' 
    AND offre.datefin IS NOT NULL 
    AND offre.id_dossier = commande.id_dossier
    and compte.id_dossier = commande.id_dossier)
    order by MONTRI asc)
    where rownum < 2

  3. #3
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    Bonjour,

    Je penses qu'avec une fonction de fenêtrage on devrait pouvoir éviter un union.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    WITH tmp as (
    SELECT ofr.id_offre, CASE ofr.tc_typecontrat WHEN 'POST' THEN cpt.code ELSE NULL END, 
    row_number() over(partition by ofr.id_offre order by ofr.tc_typecontrat desc) as rnk
    FROM offre ofr
    INNER JOIN commande com on com.id_dossier = ofr.id_dossier
    LEFT OUTER JOIN compte cpt on cpt.id_dossier = com.id_dossier
    WHERE ofr.datefin IS NOT NULL and ofr.tc_typecontrat in ('PRE', 'POST'))
     
    SELECT * 
    FROM TMP
    WHERE rnk = 1
    1 truc à adapter, c'est de virer le CASE si pour une offre PRE il n'y a pas de compte associé.
    Si il y a forcément un compte pour une commande, dans ce cas on peut transformer le left outer join en inner join.


    On pourrai simplifier le système si on a la condition suivante :
    - 1 seule offre possible par commande

    Là on pourrait enlever la fonction de fenestrage et n'utiliser que des jointures ..

  4. #4
    Membre confirmé
    Inscrit en
    Décembre 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 73
    Par défaut
    Merci pour vos réponses.
    Cela correspond bien.

    La deuxième requête proposée (WITH tmp AS, etc…) doit s’appuyer sur le résultat d’une autre requête qui est la suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select commande.id_commande from brulage, commande 
    where commande.nbtent>0
    and commande.id_commande=brulage.id_commande
    and brulage.nbpoints is null and brulage.tc_typecontrat='POST';
    Comment faire pour exécuter la deuxième requête proposée (WITH tmp AS Etc…) sur le résultat de la requête ci-dessus ?
    Dois-je utiliser un union ALL comme pour la première requête proposée ?

  5. #5
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Par défaut
    bonjour,

    non.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    WITH tmp AS (
    SELECT ofr.id_offre, CASE ofr.tc_typecontrat WHEN 'POST' THEN cpt.code ELSE NULL END, 
    row_number() over(partition BY ofr.id_offre ORDER BY ofr.tc_typecontrat DESC) AS rnk
    FROM offre ofr
    INNER JOIN commande com ON com.id_dossier = ofr.id_dossier
    LEFT OUTER JOIN compte cpt ON cpt.id_dossier = com.id_dossier
    WHERE ofr.datefin IS NOT NULL AND ofr.tc_typecontrat IN ('PRE', 'POST')
    and com.nbtent>0 and exists (select null from brulage bru where
    com.id_commande=bru.id_commande AND bru.nbpoints IS NULL AND bru.tc_typecontrat='POST'))
     
    SELECT * 
    FROM TMP
    WHERE rnk = 1

  6. #6
    Membre confirmé
    Inscrit en
    Décembre 2005
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 73
    Par défaut
    Merci.
    Cela marche bien.

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

Discussions similaires

  1. Impossible de gérer une condition
    Par Akim13 dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 14/08/2008, 14h49
  2. Réponses: 2
    Dernier message: 04/11/2006, 00h33
  3. Gérer une condition en HTML
    Par zodd dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 03/10/2006, 15h03
  4. [ms sql server 2000] top 1 dans une condition de jointure ?
    Par sylvkin dans le forum MS SQL Server
    Réponses: 3
    Dernier message: 18/10/2005, 17h10
  5. Réponses: 5
    Dernier message: 23/02/2005, 09h43

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