Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 08/06/2011, 18h01   #1
Invité de passage
 
Inscription : décembre 2005
Messages : 41
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 41
Points : 2
Points : 2
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 :
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.
Davesique est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/06/2011, 18h33   #2
Membre expérimenté
 
Avatar de NicoL__
 
Homme Nicolas
Inscription : janvier 2011
Messages : 378
Détails du profil
Informations personnelles :
Nom : Homme Nicolas
Localisation : France

Informations forums :
Inscription : janvier 2011
Messages : 378
Points : 528
Points : 528
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 :
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
NicoL__ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 08/06/2011, 19h07   #3
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
Bonjour,

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

Code :
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 ..
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 11h50   #4
Invité de passage
 
Inscription : décembre 2005
Messages : 41
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 41
Points : 2
Points : 2
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 :
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 ?
Davesique est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 12h23   #5
Expert Confirmé
 
Homme
Inscription : mai 2002
Messages : 1 638
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 29
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : mai 2002
Messages : 1 638
Points : 2 630
Points : 2 630
bonjour,

non.

Code :
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
punkoff est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 09/06/2011, 17h34   #6
Invité de passage
 
Inscription : décembre 2005
Messages : 41
Détails du profil
Informations forums :
Inscription : décembre 2005
Messages : 41
Points : 2
Points : 2
Merci.
Cela marche bien.
Davesique est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 21h02.


 
 
 
 
Partenaires

Hébergement Web