Skip site navigation (1) Skip section navigation (2)

Jointure externe

From: Sébastien Dinot <sebastien(dot)dinot(at)free(dot)fr>
To: pgsql-fr-generale(at)postgresql(dot)org
Subject: Jointure externe
Date: 2005-09-06 09:41:13
Message-ID: 20050906094113.GA5034@newtech.fr (view raw or flat)
Thread:
Lists: pgsql-fr-generale
Bonjour à tous,

J'ai un souci avec une jointure qui me semble pourtant basique et
j'aimerais que vous de disiez ce qui cloche. Où est la poutre que je
ne vois pas dans mon oeil ?

J'ai une table « type » qui contient des types d'adresse :

 type_id |   nom
---------+---------
       0 | INCONNU
       1 | GSM
       2 | FAX
       3 | EMAIL

Et une table « abo » qui contient des abonnés :

  adresse   | type | edi_id
------------+------+--------
 0612345678 |    1 |      1
 0623456789 |    1 |      1
 0634567890 |    1 |      1
 0645678901 |    1 |      2
 john(at)doo(dot)or|    3 |      3
 foo(at)bar(dot)com|    3 |      4
 0610422849 |    1 |      4
 nobody(at)nowh|    3 |      1
 0587654321 |    2 |      1
 0499887766 |    2 |      3
 [...]

Le champ abo.type est une référence sur l'identifiant type.type_id.

Le champ abo.edi_id est une référence sur un éditeur déclaré dans
d'une troisième table mais cela est sans importance ici.

Je souhaite connaître pour un éditeur (edi_id) donné, le nombre
d'abonnés de chaque type. J'exécute donc la requête suivante :

SELECT t.nom AS type, COUNT(a.*) AS nombre
  FROM abo AS a
  JOIN type AS t ON t.type_id = a.type
 WHERE a.edi_id = <EDI_ID>
 GROUP BY t.nom;

Mais comme l'éditeur n'a pas forcément des abonnés de chaque type,
cette requête me renvoie seulement les lignes correspondant aux types
trouvés. Par exemple :

 type | nombre
------+--------
 GSM  |   4799

Or, je voudrais qu'une ligne soit systématiquement produite pour
chaque type :

   type  | nombre
---------+--------
 INCONNU |      0
 GSM     |   4799
 FAX     |      0
 EMAIL   |      0

J'ai donc essayé une jointure externe :

SELECT t.nom AS type, COUNT(a.*) AS nombre
  FROM abo AS a
 RIGHT OUTER JOIN type AS t ON t.type_id = a.type
 WHERE a.edi_id = 6
 GROUP BY t.nom;

Mais cela ne fonctionne pas. J'ai aussi essayé le « LEFT OUTER JOIN »
au cas où j'aurais mal compris le sens de fonctionnement de la
jointure mais rien n'y fait. Pourtant, sur la page :

http://sql.developpez.com/sqlaz/jointures/

Il est dit :

----------------------------------------------------------------------
| SELECT colonnes
| FROM TGauche RIGHT OUTER JOIN TDroite ON condition de jointure

On recherche toutes les valeurs satisfaisant la condition de jointure
précisée dans prédicat, puis on rajoute toutes les lignes de la table
TGauche qui n'ont pas été prises en compte au titre de la satisfaction
du critère.
----------------------------------------------------------------------

Et dans la doc. de Postgres, page :

http://www.postgresql.org/docs/7.4/interactive/queries-table-expressions.html

On trouve l'exemple suivant :

----------------------------------------------------------------------
Here is another example: it calculates the total sales for each
product (rather than the total sales on all products).

| SELECT product_id, p.name, (sum(s.units) * p.price) AS sales
|   FROM products p LEFT JOIN sales s USING (product_id)
|  GROUP BY product_id, p.name, p.price;

In this example, the columns product_id, p.name, and p.price must be
in the GROUP BY clause since they are referenced in the query select
list. (Depending on how exactly the products table is set up, name and
price may be fully dependent on the product ID, so the additional
groupings could theoretically be unnecessary, but this is not
implemented yet.) The column s.units does not have to be in the GROUP
BY list since it is only used in an aggregate expression (sum(...)),
which represents the sales of a product. For each product, the query
returns a summary row about all sales of the product.
----------------------------------------------------------------------

D'après ces informations, il me semble que ma requête devrait marcher
et pourtant, ce n'est pas le cas... Pourriez-vous me dire ce qui ne va
pas ?

Je vous remercie par avance,

Sébastien

-- 
Sébastien Dinot, sebastien(dot)dinot(at)free(dot)fr
http://sebastien.dinot.free.fr/
Ne goûtez pas au logiciel libre, vous ne pourriez plus vous en passer !

Responses

pgsql-fr-generale by date

Next:From: Sébastien DinotDate: 2005-09-06 10:07:32
Subject: Re: Jointure externe
Previous:From: thomas.silviDate: 2005-09-05 20:42:09
Subject: Re: utilisation d'un array en sortie de select

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group