GROUPBY 多对多本身
GROUPBY many to many with itself
我有一个用户 table,它与自己有多对多的关系,我想获得具有这种特定关系的所有用户对。问题是,在关系 table 中,我这样存储用户:
+------+---------------+
| User | relation |
+------+---------------+
| id | left_user_id |
| name | right_user_id |
| ... | ... |
+------+---------------+
所以当我做一个基本的
SELECT count(*)
FROM relation LEFT OUTER JOIN user AS user_1 ON user_1.id = relation.left_user_id
LEFT OUTER JOIN user AS user_2 ON user_2.id = relation.right_user_id
GROUP BY left_user_id, right_user_id;
我有时会得到同一对的两个结果(例如,有时 (Adam, Eva) 和 (Eva, Adam) 是同一对)。我想要实现的只是一对:(Adam, Eva)。
如何实现?
您可以使用函数 least()
和 greatest()
:
SELECT count(*)
FROM relation r
LEFT OUTER JOIN user AS user_1 ON user_1.id = r.left_user_id
LEFT OUTER JOIN user AS user_2 ON user_2.id = r.right_user_id
GROUP BY LEAST(r.left_user_id, r.right_user_id), GREATEST(r.left_user_id, r.right_user_id);
或者在这种情况下您不需要连接:
SELECT count(*)
FROM relation
GROUP BY LEAST(left_user_id, right_user_id), GREATEST(left_user_id, right_user_id);
left join
应该不是必需的。关键是简单地使用 least()
和 greatest()
。那将是:
SELECT LEAST(r.left_user_id, r.right_user_id) as user_id_1,
GREATEST(r.left_user_id, r.right_user_id) as user_id_2,
COUNT(*)
FROM relation
GROUP BY user_id_1, user_id_2;
这种方法的一个警告是结果集中的对可能不在原始数据中——按照那个顺序。所以,如果你在数据中有一次 "Eve"/"Adam",那么它将是 return:"Adam"/"Eve"/1。如有必要,可以解决这个问题。
我有一个用户 table,它与自己有多对多的关系,我想获得具有这种特定关系的所有用户对。问题是,在关系 table 中,我这样存储用户:
+------+---------------+
| User | relation |
+------+---------------+
| id | left_user_id |
| name | right_user_id |
| ... | ... |
+------+---------------+
所以当我做一个基本的
SELECT count(*)
FROM relation LEFT OUTER JOIN user AS user_1 ON user_1.id = relation.left_user_id
LEFT OUTER JOIN user AS user_2 ON user_2.id = relation.right_user_id
GROUP BY left_user_id, right_user_id;
我有时会得到同一对的两个结果(例如,有时 (Adam, Eva) 和 (Eva, Adam) 是同一对)。我想要实现的只是一对:(Adam, Eva)。
如何实现?
您可以使用函数 least()
和 greatest()
:
SELECT count(*)
FROM relation r
LEFT OUTER JOIN user AS user_1 ON user_1.id = r.left_user_id
LEFT OUTER JOIN user AS user_2 ON user_2.id = r.right_user_id
GROUP BY LEAST(r.left_user_id, r.right_user_id), GREATEST(r.left_user_id, r.right_user_id);
或者在这种情况下您不需要连接:
SELECT count(*)
FROM relation
GROUP BY LEAST(left_user_id, right_user_id), GREATEST(left_user_id, right_user_id);
left join
应该不是必需的。关键是简单地使用 least()
和 greatest()
。那将是:
SELECT LEAST(r.left_user_id, r.right_user_id) as user_id_1,
GREATEST(r.left_user_id, r.right_user_id) as user_id_2,
COUNT(*)
FROM relation
GROUP BY user_id_1, user_id_2;
这种方法的一个警告是结果集中的对可能不在原始数据中——按照那个顺序。所以,如果你在数据中有一次 "Eve"/"Adam",那么它将是 return:"Adam"/"Eve"/1。如有必要,可以解决这个问题。