views:

35

answers:

2

Take a look at the following mySQL query:

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

The above query first creates a set of ALL the friends.sub's via the inner query, and then the outer query selects a list of users where user ids are contained within the set created by the inner query (ie the union of the two sets).

And this works fine. But if you needed the inner set to contain not only the subs where dom = 1, but also the doms where sub = 1, like so: Outer query remains same as above, pure pseudocode:

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

Is it possible to make this sort of functionality with the inner query??

Any help or assistance appreciated guys;-D

Thanks a lot guys, my headache is gone now!

+1  A: 

Try this:

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)
Alec
Nice work guys! is this the most optimal approach??
DJDonaL3000
@DJDonaL3000: Yes, I believe so. If you plan to have many records, you should make sure that `sub` and `dom` are indexed properly. You could use the MySQL [`EXPLAIN`](http://dev.mysql.com/doc/refman/5.0/en/explain.html) command to see if the query is using an index or not.
Daniel Vassallo
How is users and friends a self-join when they're different tables?
Xepoch
Thanks again Dan. Feel free to edit any errors or omissions within my posts...
DJDonaL3000
+1  A: 

I'm not sure if I correctly understand what sub and dom represent, but it looks like you can use a UNION in there:

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 
       );

Test case:

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);

Result:

+-------+---------+
| fname | lname   |
+-------+---------+
| Peter | Brown   |
| Jack  | Green   |
| Kevin | Jackson |
+-------+---------+
3 rows in set (0.00 sec)

That said, @Alec's solution is probably more efficient.

Daniel Vassallo
doms and subs simply represent user ids. If user 1 is user 2s friend dom = 1 and sub = 2
DJDonaL3000
Nice work... 10 out of 10 mate;-D
DJDonaL3000