[SQL] - Passez moi le JOIN !

Je fais appel aux cerveaux éclairés (au fait cette expression est ignoble ?) de la Cafzone pour m’aider à résoudre un problème.

Je dois modéliser une requête SQL dans le cadre d’un de mes projets professionnels et aucun de mes collègues n’a réussi à m’aider, je commence à sérieusement saturer.

Le SGBD utilisé est DB2.

Voici la situation. Par souci de simplification et de discrétion, les noms des tables ont été changés.

Tout d’abord, le MCD :

Ensuite voici la requête que j’ai pour l’instant écrite. Celle-ci ne fonctionne pas comme je le désire.

SELECT   V1.NOM AS RESPONSABLE,   V2.NOM AS VENDEUR FROM   ENTITE E   LEFT JOIN VENDEUR V1 ON E.FK_VENDEUR_RESPONSABLE = V1.ID_VENDEUR LEFT JOIN DEPARTEMENT D ON E.FK_DEPARTEMENT = D.ID_DEPARTEMENT   INNER JOIN ASSIGNATION A   ON D.ID_DEPARTEMENT = A.FK_DEPARTEMENT   INNER JOIN VENDEUR V2   ON V2.ID_VENDEUR = A.FK_VENDEUR

En gros, il faut savoir qu’une ligne d’entité peut avoir un responsable (donc la liaison est directe entre vendeur et departement) et a un secteur assigné à un vendeur.

Concernant les remarque éventuelles de conception que vous allez faire, oui il peut ne pas y avoir de responsable, d’où la jointure externe. Et oui, il n’y a qu’un vendeur malgré la liaison père-père entre vendeur et departement. Celle-ci est présente car ma requête est plus compliquée (il y a des histoires de bornes de dates, bref).

Pour info, cette jointure fonctionne

ENTITE E   LEFT JOIN VENDEUR V1 ON E.FK_VENDEUR_RESPONSABLE = V1.ID_VENDEUR
Celle ci aussi
ENTITE E LEFT JOIN DEPARTEMENT D   ON E.FK_DEPARTEMENT = D.ID_DEPARTEMENT   INNER JOIN ASSIGNATION A   ON D.ID_DEPARTEMENT = A.FK_DEPARTEMENT   INNER JOIN VENDEUR V2   ON V2.ID_VENDEUR = A.FK_VENDEUR
Mais les deux ensemble ne sont pas bien écrites/définies/dans le mauvais ordre car je n'arrive pas à afficher les infos que je désire - je n'affiche que les résultats de la deuxième requête.

Pouvez vous m’aider à écrire des jointures correctes s’il-vous-plaît ?

Bizarre ton MCD.

Vendeur et vendeur responsable, on les voit dans ta requête mais dans ton MCD on se demande d’où ils viennent. Ah oui on les voit dans des FK qui n’ont rien à faire dans un MCD.

Et c’est quoi ces identifiants_1 ?

Quoiqu’il en soit, mets des parenthèses dans tes jointures. Je ne comprends pas si il y a une jointure entre 2 tables ou entre une partie des jointures déjà effectuées et le reste.

Sinon tu peux essayer cela:

SELECT FROM (ta première requête ) Table_alias_1 jointure (ta 2é requête de la mort) Table_alias 2
plutôt que  
SELECT FROM (une grosse requête de la mort) [/quote]

Ce message a été édité par phili_b le 13/02/2004

[quote]Vendeur et vendeur responsable, on les voit dans ta requête mais dans ton MCD on se demande d’où ils viennent. Ah oui on les voit dans des FK qui n’ont rien à faire dans un MCD.
Je les ai affichées pour que vous compreniez où se trouve chaque champs. Je sais qu’on n’affiche normalement pas les FK dans les MCD mais en l’occurence ça me semblait plus clair comme ça.

[quote]Et c’est quoi ces identifiants_1 ?

C'est PowerAMC qui a généré ça. J'ai pas eu envie de passer par paint pour les effacer.

Je vais essayer ta solution, merci de ta réponse.

Edit : bon, j’ai “résolu” le problème en faisant passer le deuxième champs dans un sous-select… C’est pas propre, pas optimisé mais ça marche.
Ce message a été édité par use-writer le 13/02/2004

As-tu utilisé CASE ou COALESCE pour traiter tes valeurs nulles générées par des jointures externes ?

Cela permet de remplacer la valeur d’un champ par une constante lorsque ce champ est nul. On peut aussi remplacer la valeur de ce champ, lorsqu’il est null, par un champ d’une autre table.
Ce message a été édité par phili_b le 15/02/2004

[quote]As-tu utilisé CASE ou COALESCE pour traiter tes valeurs nulles générées par des jointures externes ?

Cela permet de remplacer la valeur d’un champ par une constante lorsque ce champ est nul. On peut aussi remplacer la valeur de ce champ, lorsqu’il est null, par un champ d’une autre table.
Ce message a été édité par phili_b le 15/02/2004[/quote]Oui oui, j’utilise coalesce constamment lorsque j’ai des jointures externes pouvant ne renvoyer aucune valeur.

Sinon j’ai une autre question SQL DB2, et puisque tu semble bien connaître ce SGBDR je vais la poser ici.

Pour afficher un libellé descriptif constitué de plusieurs champs de type varchar et decimal j’utilise la fonction de concaténation CONCAT.

De manière à ce que la concaténation fonctionne, il faut convertir les champs décimaux en chaîne. A cette fin j’utilise la fonction CHAR(), malheureusement celle-ci transcrit le nombre en chaîne fixe selon la taille du champs (par exemple, un champs de valeur 12,55 renverra “000012,550” car le champs est en précision (9,3)).

Comment faire pour renvoyer les valeurs de type décimal de manière plus esthétique ?

Comme je te disais, je connais moins bien DB2 que Oracle et SQL server, dès lors que l’on sort du SQL standard, comme les formatages de dates ou de données.

Mais voici des liens sur DB2:

IBM Knowledge base sur DB2
IBM Support on line sur DB2
DB2 Magazine
SQL Cookbook sur DB2 <-- Regardes celui-là pour ton problème, pas mal fait (Trucs et Astuces ) 

Ce message a été édité par phili_b le 16/02/2004

Ok, merci pour les liens je vais y jeter un oeil.

En attendant j’ai utilisé cette solution qui si elle est barbare a l’avantage de fonctionner :

SELECT T.LIBELLE CONCAT '('CONCAT (COALESCE(SUBSTR(CHAR(BIGINT(T.PRIX *1000)),1,LENGTH(RTRIM(CHAR(BIGINT(T.PRIX * 1000))))-3)||'.'|| SUBSTR(CHAR(BIGINT(T.PRIX*1000)),1+LENGTH(RTRIM(CHAR(BIGINT(T.PRIX*1000))))-3,3),'0')) CONCAT ')' AS LIBELLE FROM TARIF T[/quote]Merci IBM...

ps : au fait, IBM a eu l’ingénieuse idée d’intégrer les bien connues fonctions LTRIM et RTRIM… Je leur suggère pour leur prochaine évol’ la fonction TRIM() qui allègerait un peut les requêtes !