這是導致一切
SELECT * FROM (SELECT * FROM
(SELECT sender_user_id,receiver_user_id FROM user_friendships) A
UNION
(SELECT receiver_user_id,sender_user_id FROM user_friendships)) B
UNION
SELECT * FROM
(SELECT uf1.sender_user_id,uf2.receiver_user_id
FROM user_friendships uf1 INNER JOIN user_friendships uf2
ON uf1.receiver_user_id = uf2.sender_user_id) C
UNION
SELECT * FROM
(SELECT uf1.receiver_user_id,uf2.sender_user_id
FROM user_friendships uf1 INNER JOIN user_friendships uf2
ON uf1.sender_user_id = uf2.receiver_user_id) D;
注意
- 子查詢A和B是第一代雙向查詢
- 子查詢C和d是第二代雙向
以下是您的示例數據:
DROP DATABASE IF EXISTS friends;
CREATE DATABASE friends;
USE friends
CREATE TABLE users
(id int not null auto_increment,
name varchar(10),primary key (id));
insert into users (name) values
('bill'),('bob'),('sam'),('ben');
CREATE TABLE user_friendships
(sender_user_id int not null,
receiver_user_id int not null,
primary key (sender_user_id,receiver_user_id),
unique key (receiver_user_id,sender_user_id));
insert into user_friendships values
(1,2),(2,3),(2,4);
這是你的樣本數據加載
mysql> DROP DATABASE IF EXISTS friends;
(id int not null auto_increment,
name varchar(10),primary key (id));
insert into users (name) values
('bill'),('bob'),('sam'),('ben');
CREATE TABLE user_friendships
(sender_user_id int not null,
receiver_user_id int not null,
primary key (sender_user_id,receiver_user_id),
unique key (receiver_user_id,sender_user_id));
insert into user_friendships values
(1,2),(2,3),(2,4);
Query OK, 2 rows affected (0.08 sec)
mysql> CREATE DATABASE friends;
Query OK, 1 row affected (0.00 sec)
mysql> USE friends
Database changed
mysql> CREATE TABLE users
-> (id int not null auto_increment,
-> name varchar(10),primary key (id));
Query OK, 0 rows affected (0.08 sec)
mysql> insert into users (name) values
-> ('bill'),('bob'),('sam'),('ben');
Query OK, 4 rows affected (0.07 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> CREATE TABLE user_friendships
-> (sender_user_id int not null,
-> receiver_user_id int not null,
-> primary key (sender_user_id,receiver_user_id),
-> unique key (receiver_user_id,sender_user_id));
Query OK, 0 rows affected (0.06 sec)
mysql> insert into user_friendships values
-> (1,2),(2,3),(2,4);
Query OK, 3 rows affected (0.06 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> select * from users;
+----+------+
| id | name |
+----+------+
| 1 | bill |
| 2 | bob |
| 3 | sam |
| 4 | ben |
+----+------+
4 rows in set (0.00 sec)
mysql> select * from user_friendships;
+----------------+------------------+
| sender_user_id | receiver_user_id |
+----------------+------------------+
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
+----------------+------------------+
3 rows in set (0.00 sec)
mysql>
這裏是「一切查詢」
mysql> SELECT * FROM (SELECT * FROM
-> (SELECT sender_user_id,receiver_user_id FROM user_friendships) A
-> UNION
-> (SELECT receiver_user_id,sender_user_id FROM user_friendships)) B
-> UNION
-> SELECT * FROM
-> (SELECT uf1.sender_user_id,uf2.receiver_user_id
-> FROM user_friendships uf1 INNER JOIN user_friendships uf2
-> ON uf1.receiver_user_id = uf2.sender_user_id) C
-> UNION
-> SELECT * FROM
-> (SELECT uf1.receiver_user_id,uf2.sender_user_id
-> FROM user_friendships uf1 INNER JOIN user_friendships uf2
-> ON uf1.sender_user_id = uf2.receiver_user_id) D;
+----------------+------------------+
| sender_user_id | receiver_user_id |
+----------------+------------------+
| 1 | 2 |
| 2 | 3 |
| 2 | 4 |
| 2 | 1 |
| 3 | 2 |
| 4 | 2 |
| 1 | 3 |
| 1 | 4 |
| 3 | 1 |
| 4 | 1 |
+----------------+------------------+
10 rows in set (0.00 sec)
mysql>
現在的運行看用戶1只是關係,只要使用此查詢
SELECT * FROM (
SELECT * FROM (SELECT * FROM
(SELECT sender_user_id,receiver_user_id FROM user_friendships) A
UNION
(SELECT receiver_user_id,sender_user_id FROM user_friendships)) B
UNION
SELECT * FROM
(SELECT uf1.sender_user_id,uf2.receiver_user_id
FROM user_friendships uf1 INNER JOIN user_friendships uf2
ON uf1.receiver_user_id = uf2.sender_user_id) C
UNION
SELECT * FROM
(SELECT uf1.receiver_user_id,uf2.sender_user_id
FROM user_friendships uf1 INNER JOIN user_friendships uf2
ON uf1.sender_user_id = uf2.receiver_user_id) D) everything
WHERE (sender_user_id=1 and receiver_user_id<>1)
or (sender_user_id<>1 and receiver_user_id=1);
這裏是輸出
mysql> SELECT * FROM (
-> SELECT * FROM (SELECT * FROM
-> (SELECT sender_user_id,receiver_user_id FROM user_friendships) A
-> UNION
-> (SELECT receiver_user_id,sender_user_id FROM user_friendships)) B
-> UNION
-> SELECT * FROM
-> (SELECT uf1.sender_user_id,uf2.receiver_user_id
-> FROM user_friendships uf1 INNER JOIN user_friendships uf2
-> ON uf1.receiver_user_id = uf2.sender_user_id) C
-> UNION
-> SELECT * FROM
-> (SELECT uf1.receiver_user_id,uf2.sender_user_id
-> FROM user_friendships uf1 INNER JOIN user_friendships uf2
-> ON uf1.sender_user_id = uf2.receiver_user_id) D) everything
-> WHERE (sender_user_id=1 and receiver_user_id<>1)
-> or (sender_user_id<>1 and receiver_user_id=1);
+----------------+------------------+
| sender_user_id | receiver_user_id |
+----------------+------------------+
| 1 | 2 |
| 2 | 1 |
| 1 | 3 |
| 1 | 4 |
| 3 | 1 |
| 4 | 1 |
+----------------+------------------+
6 rows in set (0.00 sec)
mysql>
現在掛鉤frmo用戶表中的名稱是這樣的:
SELECT u1.name,u2.name FROM (
SELECT * FROM (SELECT * FROM
(SELECT sender_user_id,receiver_user_id FROM user_friendships) A
UNION
(SELECT receiver_user_id,sender_user_id FROM user_friendships)) B
UNION
SELECT * FROM
(SELECT uf1.sender_user_id,uf2.receiver_user_id
FROM user_friendships uf1 INNER JOIN user_friendships uf2
ON uf1.receiver_user_id = uf2.sender_user_id) C
UNION
SELECT * FROM
(SELECT uf1.receiver_user_id,uf2.sender_user_id
FROM user_friendships uf1 INNER JOIN user_friendships uf2
ON uf1.sender_user_id = uf2.receiver_user_id) D) everything
INNER JOIN users u1 ON everything.sender_user_id = u1.id
INNER JOIN users u2 ON everything.receiver_user_id = u2.id
WHERE (sender_user_id=1 and receiver_user_id<>1)
or (sender_user_id<>1 and receiver_user_id=1);
這裏是輸出
mysql> SELECT u1.name,u2.name FROM (
-> SELECT * FROM (SELECT * FROM
-> (SELECT sender_user_id,receiver_user_id FROM user_friendships) A
-> UNION
-> (SELECT receiver_user_id,sender_user_id FROM user_friendships)) B
-> UNION
-> SELECT * FROM
-> (SELECT uf1.sender_user_id,uf2.receiver_user_id
-> FROM user_friendships uf1 INNER JOIN user_friendships uf2
-> ON uf1.receiver_user_id = uf2.sender_user_id) C
-> UNION
-> SELECT * FROM
-> (SELECT uf1.receiver_user_id,uf2.sender_user_id
-> FROM user_friendships uf1 INNER JOIN user_friendships uf2
-> ON uf1.sender_user_id = uf2.receiver_user_id) D) everything
-> INNER JOIN users u1 ON everything.sender_user_id = u1.id
-> INNER JOIN users u2 ON everything.receiver_user_id = u2.id
-> WHERE (sender_user_id=1 and receiver_user_id<>1)
-> or (sender_user_id<>1 and receiver_user_id=1);
+------+------+
| name | name |
+------+------+
| bob | bill |
| sam | bill |
| ben | bill |
| bill | bob |
| bill | sam |
| bill | ben |
+------+------+
6 rows in set (0.00 sec)
mysql>
試試看!
CAVEAT
胡克使用左邊的名字,而不是JOIN內蒙古JOIN保留數被退回
SELECT u1.name,u2.name FROM (
SELECT * FROM (SELECT * FROM
(SELECT sender_user_id,receiver_user_id FROM user_friendships) A
UNION
(SELECT receiver_user_id,sender_user_id FROM user_friendships)) B
UNION
SELECT * FROM
(SELECT uf1.sender_user_id,uf2.receiver_user_id
FROM user_friendships uf1 INNER JOIN user_friendships uf2
ON uf1.receiver_user_id = uf2.sender_user_id) C
UNION
SELECT * FROM
(SELECT uf1.receiver_user_id,uf2.sender_user_id
FROM user_friendships uf1 INNER JOIN user_friendships uf2
ON uf1.sender_user_id = uf2.receiver_user_id) D) everything
LEFT JOIN users u1 ON everything.sender_user_id = u1.id
LEFT JOIN users u2 ON everything.receiver_user_id = u2.id
WHERE (sender_user_id=1 and receiver_user_id<>1)
or (sender_user_id<>1 and receiver_user_id=1);
這裏是輸出
mysql> SELECT u1.name,u2.name FROM (
-> SELECT * FROM (SELECT * FROM
-> (SELECT sender_user_id,receiver_user_id FROM user_friendships) A
-> UNION
-> (SELECT receiver_user_id,sender_user_id FROM user_friendships)) B
-> UNION
-> SELECT * FROM
-> (SELECT uf1.sender_user_id,uf2.receiver_user_id
-> FROM user_friendships uf1 INNER JOIN user_friendships uf2
-> ON uf1.receiver_user_id = uf2.sender_user_id) C
-> UNION
-> SELECT * FROM
-> (SELECT uf1.receiver_user_id,uf2.sender_user_id
-> FROM user_friendships uf1 INNER JOIN user_friendships uf2
-> ON uf1.sender_user_id = uf2.receiver_user_id) D) everything
-> LEFT JOIN users u1 ON everything.sender_user_id = u1.id
-> LEFT JOIN users u2 ON everything.receiver_user_id = u2.id
-> WHERE (sender_user_id=1 and receiver_user_id<>1)
-> or (sender_user_id<>1 and receiver_user_id=1);
+------+------+
| name | name |
+------+------+
| bill | bob |
| bob | bill |
| bill | sam |
| bill | ben |
| sam | bill |
| ben | bill |
+------+------+
6 rows in set (0.00 sec)
mysql>
感謝您的回覆順序。這看起來更像我在找什麼,但是我收到了第2行的語法錯誤,假設它與if語句和mysql有關?顯然,我已經用用戶標識替換了你的用戶標識。 – leejmurphy 2012-01-06 22:27:12
第2行有一個點而不是逗號(稍後會有相應的行)對不起,我總是發生在我身上。 – 2012-01-06 22:36:29
你是對的,謝謝。如果我使用用戶ID 1,它只返回用戶ID 2.它也應該返回3和4,因爲他們是2的朋友。不知道第二代的哪部分不正確 – leejmurphy 2012-01-06 22:47:23