2010-10-09 12 views
1

Jetez un oeil à la requête mySQL suivante:MySQL jointure réflexive question

SELECT fname,lname FROM users WHERE users.id IN (SELECT sub FROM friends WHERE friends.dom = 1) 

La requête ci-dessus crée d'abord un ensemble de toutes les années friends.sub par la requête interne, puis la requête externe sélectionne une liste de les utilisateurs où les identifiants d'utilisateur sont contenus dans l'ensemble créé par la requête interne (c'est-à-dire l'union des deux ensembles).

Et cela fonctionne très bien. Mais si vous avez besoin de l'ensemble intérieur pour contenir non seulement les sous-marins où dom = 1, mais aussi les Doms où sub = 1, comme suit: requête externe reste comme ci-dessus, pseudocode pur:

(SELECT sub FROM friends WHERE friends.dom = 1) 
***AND*** 
(SELECT dom FROM friends WHERE friends.sub = 1) 

Est-il possible de faire ce genre de fonctionnalité avec la requête interne ??

Toute aide ou assistance gars apprécié ;-D

Merci beaucoup les gars, mon mal de tête a disparu maintenant!

Répondre

1

Essayez ceci:

SELECT u.fname, u.lname 
FROM users u 
INNER JOIN friends f 
    ON (u.id = f.sub AND f.dom = 1) 
    OR (u.id = f.dom AND f.sub = 1)
+0

Beau travail les gars! est-ce l'approche la plus optimale? –

+0

@ DJDonaL3000: Oui, je le crois. Si vous prévoyez d'avoir plusieurs enregistrements, vous devez vous assurer que 'sub' et' dom' sont indexés correctement. Vous pouvez utiliser la commande MySQL ['EXPLAIN'] (http://dev.mysql.com/doc/refman/5.0/en/explain.html) pour voir si la requête utilise un index ou non. –

+0

Comment les utilisateurs et les amis se connectent-ils automatiquement lorsqu'ils sont différents? – Xailor

1

Je ne sais pas si je comprends bien ce que sub et dom représentent, mais il semble que vous pouvez utiliser un UNION là:

SELECT fname, lname 
FROM users 
WHERE users.id IN 
     ( 
      SELECT sub FROM friends WHERE friends.dom = 1 
      UNION 
      SELECT dom FROM friends WHERE friends.sub = 1 
     ); 

cas de test :

CREATE TABLE users (id int, fname varchar(10), lname varchar(10)); 
CREATE TABLE friends (dom int, sub int); 

INSERT INTO users VALUES (1, 'Bob', 'Smith'); 
INSERT INTO users VALUES (2, 'Peter', 'Brown'); 
INSERT INTO users VALUES (3, 'Jack', 'Green'); 
INSERT INTO users VALUES (4, 'Kevin', 'Jackson'); 
INSERT INTO users VALUES (5, 'Steven', 'Black'); 

INSERT INTO friends VALUES (1, 2); 
INSERT INTO friends VALUES (1, 3); 
INSERT INTO friends VALUES (4, 1); 
INSERT INTO friends VALUES (3, 4); 
INSERT INTO friends VALUES (5, 2); 

Résultat:Cela signifie que @Alec's solution est probablement plus efficace.

+0

Doms et sous-marins représentent simplement les ID utilisateur. Si l'utilisateur 1 est l'utilisateur 2s friend dom = 1 et sub = 2 –

+0

Beau travail ... 10 sur 10 mate ;-D –