2009-05-25 9 views
12

Je me demandais, est-il possible de joindre le résultat d'une requête avec lui-même?Auto-jointure d'une sous-requête

(J'utilise PostgreSQL)

+1

Pourriez-vous donner un exemple de ce que vous essayez de faire? –

Répondre

26

Vous pouvez le faire avec AVEC:

WITH subquery AS(
    SELECT * FROM TheTable 
) 
SELECT * 
FROM subquery q1 
JOIN subquery q2 on ... 

ou en créant une vue contenant la requête, et se joindre à ce:

SELECT * 
FROM TheView v1 
JOIN TheView v2 on ... 

Ou l'approche par force brute: saisissez deux fois la sous-requête:

SELECT * 
FROM (
    SELECT * FROM TheTable 
) sub1 
LEFT JOIN (
    SELECT * FROM TheTable 
) sub2 ON ... 
+0

PostgreSQL ne prend pas en charge les requêtes WITH dans la dernière version, 8.3, selon http://www.postgresql.org/docs/8.3/interactive/unsupported-features-sql-standard.html. – markusk

+0

Si vous pouvez passer à la version 8.4, actuellement en version bêta, WITH est enfin là, voir http://www.postgresql.org/docs/8.4/static/queries-with.html –

+0

Puisque ma sous-requête est quelque peu complexe, je vais essayez d'abord avec une vue, puis la solution "force brute" .. Finalement, je vais passer à utiliser avec quand pgsql 8.4 navires :) Merci à tout le monde! – Joril

2

Voulez-vous dire, le résultat d'une requête sur une table, à cette même table. Si oui, alors oui, c'est possible ... par ex.

--Bit of a contrived example but... 
SELECT * 
FROM Table 
INNER JOIN 
(
    SELECT 
      UserID, Max(Login) as LastLogin 
    FROM 
      Table 
    WHERE 
      UserGroup = 'SomeGroup' 
    GROUP BY 
      UserID 

) foo 
ON Table.UserID = Foo.UserID AND Table.Login = Foo.LastLogin 
+0

Désolé, il suffit de remarquer votre commentaire "J'utilise PostGres". Je ne sais pas si ce qui précède est syntaxiquement correct dans postgres. –

+0

C'est bien AFAICS (sauf peut-être pour le conflit de cas 'foo' vs 'Foo' ;-). –

+0

@Eoin: Eh bien, je voulais dire rejoindre le _results_ des requêtes, mais merci pour votre aide tout de même :) – Joril

0

Oui, tout alias les requêtes:

SELECT * 
FROM (
     SELECT * 
     FROM table 
     ) t1 
JOIN (
     SELECT * 
     FROM table 
     ) t2 
ON  t1.column < t2.other_column