PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 23/08/2011 17:01:31

HadanMarv
Membre

Left join ambigu

Je reprends actuellement une application en main. Un existant relativement conséquent.
J'ai pas mal d'exemple de requête relativement complexe j'en prend une au hazard car je n'arrive pas à comprendre son fonctionnement.
Vous pourrez constater que les deux lefts joins avec sous requête ont une clause on sur un champ n'existant pas.
c'est surement logique mais là je l'ai pas.

Voici les ddl :

CREATE TABLE objets
(
  obj_id integer NOT NULL DEFAULT 0, -- Identifiant unique du objet
  obj_module character varying(15) NOT NULL DEFAULT '0'::character varying,
  obj_nom character varying(30) NOT NULL DEFAULT '0'::character varying,
  obj_type smallint,
  obj_actiondisp smallint,
  CONSTRAINT objets_pkey PRIMARY KEY (obj_id),
  CONSTRAINT obj_module_nom_u UNIQUE (obj_module, obj_nom)
)

CREATE TABLE objets_actions
(
  oba_id integer NOT NULL DEFAULT 0, -- Identifiant unique du table
  oba_seq character varying(1) NOT NULL DEFAULT '0'::character varying,
  oba_idobj integer NOT NULL DEFAULT 0, -- Id objet (Clef etrangere OBJETS.OBJ_ID)
  oba_droitsdisp smallint,
  oba_emplacement smallint,
  CONSTRAINT objets_actions_pkey PRIMARY KEY (oba_id),
  CONSTRAINT oba_obj FOREIGN KEY (oba_idobj)
      REFERENCES objets (obj_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT oba_seq_idobj_u UNIQUE (oba_seq, oba_idobj)
)

CREATE TABLE profils
(
  pro_id integer NOT NULL DEFAULT 0, -- Identifiant unique de la profil
  pro_nom character varying(40) NOT NULL DEFAULT NULL::character varying,
  pro_comment character varying(255) DEFAULT NULL::character varying,
  CONSTRAINT profils_pkey PRIMARY KEY (pro_id),
  CONSTRAINT pro_idact_nom_u UNIQUE (pro_nom)
)

CREATE TABLE utilisateurs
(
  usr_id integer NOT NULL DEFAULT 0, -- Identifiant unique de la utilisateur
  usr_idpro integer, -- Id profil (Clef etrangere PROFILS.PRO_ID)
  usr_nomcompte character varying(20) NOT NULL DEFAULT ''::character varying,
  usr_pass character varying(32) DEFAULT NULL::character varying,
  usr_nom character varying(40) DEFAULT NULL::character varying,
  usr_prenom character varying(40) DEFAULT NULL::character varying,
  usr_email character varying(60) DEFAULT NULL::character varying,
  CONSTRAINT utilisateurs_pkey PRIMARY KEY (usr_id),
  CONSTRAINT usr_pro FOREIGN KEY (usr_idpro)
      REFERENCES profils (pro_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT usr_nomcompte_u UNIQUE (usr_nomcompte)
)

CREATE TABLE droits
(
  dro_idpro integer NOT NULL DEFAULT 0, -- Id profil (Clef etrangere PROFILS.PRO_ID)
  dro_idoba integer NOT NULL DEFAULT 0, -- Id object action (Clef etrangere OBJETS_ACTIONS.OBA_ID)
  dro_visible smallint,
  dro_droits smallint,
  dro_popup smallint,
  CONSTRAINT droits_pkey PRIMARY KEY (dro_idpro, dro_idoba),
  CONSTRAINT dro_oba FOREIGN KEY (dro_idoba)
      REFERENCES objets_actions (oba_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT dro_pro FOREIGN KEY (dro_idpro)
      REFERENCES profils (pro_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)

et la requête

SELECT OBJ_ID, OBA_SEQ, OBJ_MODULE, OBJ_NOM, OBA_DROITSDISP, COALESCE(T1.LENGTH,0) AS LENGTH, COALESCE(DRO_VISIBLE,1) AS DRO_VISIBLE,
    CASE WHEN OBJ_TYPE IN (2,3) THEN COALESCE(DRO_DROITS,2) ELSE COALESCE(DRO_DROITS,0) END AS DRO_DROITS,
    CASE WHEN OBJ_TYPE IN (2,3) THEN COALESCE(DRO_POPUP,2) ELSE COALESCE(DRO_POPUP,0) END AS DRO_POPUP
FROM OBJETS
LEFT JOIN OBJETS_ACTIONS ON OBA_IDOBJ = OBJ_ID
LEFT JOIN (
    SELECT
        PRO_ID
    FROM PROFILS
    LEFT JOIN UTILISATEURS ON USR_IDPRO=PRO_ID
    WHERE PRO_ISUPP = 0 AND USR_ISUPP=0 AND PRO_ID > 0
    GROUP BY PRO_ID
) AS T ON OBA_DROITSDISP = 3
LEFT JOIN (
    SELECT
        COUNT(DISTINCT PRO_ID) AS LENGTH
    FROM PROFILS
    LEFT JOIN UTILISATEURS ON USR_IDPRO=PRO_ID
    WHERE PRO_ISUPP = 0 AND USR_ISUPP=0 AND PRO_ID > 0
) AS T1 ON OBA_DROITSDISP = 3
LEFT JOIN DROITS ON DRO_IDOBA = OBA_ID AND DRO_IDPRO = T.PRO_ID
WHERE OBJ_TYPE IN (2,3,4,6,7,9,11) AND OBJ_ACTIONDISP > 0 AND OBA_DROITSDISP > 0
ORDER BY OBJ_ID ASC, OBA_SEQ ASC, T.PRO_ID ASC, LENGTH ASC

Merci d'avande de vos lumières.

Hors ligne

#2 23/08/2011 17:46:24

gleu
Administrateur

Re : Left join ambigu

Quelle clause ?


Guillaume.

Hors ligne

#3 23/08/2011 17:51:14

HadanMarv
Membre

Re : Left join ambigu

<code>LEFT JOIN (
    SELECT
        PRO_ID
    FROM PROFILS
    LEFT JOIN UTILISATEURS ON USR_IDPRO=PRO_ID
    WHERE PRO_ISUPP = 0 AND USR_ISUPP=0 AND PRO_ID > 0
    GROUP BY PRO_ID
) AS T ON OBA_DROITSDISP = 3 <code>

c'est le on que je ne comprends pas

Hors ligne

#4 23/08/2011 22:42:16

gleu
Administrateur

Re : Left join ambigu

J'avoue que je ne Comprends pas non plus cette jointure.


Guillaume.

Hors ligne

#5 24/08/2011 11:04:23

flo
Membre

Re : Left join ambigu

J'ai du mal aussi.

Alors  j'ai fait le test :
cela fait un produit cartésien, sauf que pour les lignes où la condition n'est pas respectée, on n'a rien dans les colonnes de la table "de droite".

Exemple :

test=# select * from table1 left join table2 on table1.valeurs1 = 'b';
 idtable1 | valeurs1 | idtable2 | valeur2
----------+----------+----------+---------
        1 | a        |          |
        2 | b        |        1 | 1
        2 | b        |        2 | 2
        2 | b        |        3 | 3
        2 | b        |        4 | 4
        3 | c        |          |
        4 | d        |          |
        5 | e        |          |
        6 | f        |          |
(9 lignes)

J'avoue que je ne vois pas l'intérêt du truc, comme cela.

Hors ligne

Pied de page des forums