我希望这不是重复的,我已经搜索了一段时间没有任何有用的结果。
我有一个对象表(带有主键)和一个关系表。每个关系通过外键引用两个对象(obj_1 和 obj_2)。 obj_1 和 obj_2 的组合是唯一的,因此我可以表示某种网络。
现在我想选择位于至少两个其他点之间的点(例如,有多个连接)。我通过以下查询实现了这一点:
select r1.obj_1, r1.obj_2 as hop, r2.obj_2
from t_relations r1
inner join t_relations r2 on r1.obj_2 = r2.obj_1
现在,我的问题是我还想查看每个跃点拥有的连接数,但是没有过滤(我需要选择所有行,因此分组依据不是一个选项)。我怎样才能做到这一点?
<小时/>根据要求,一些示例数据。为了简单起见,我假设 t_relations 中的数字是实际对象。
关系
ID | obj_1 | obj_2
1 | T1 | T2
2 | T3 | T2
3 | T4 | T2
4 | T4 | T3
预期输出:
obj_1 | hop | obj_2 | count
T1 | T2 | T3 | 3 # 3 connections with 2
T3 | T2 | T4 | 3
T4 | T2 | T1 | 3
T4 | T3 | T1 | 1 # 1 connection via 3
T2 | T4 | T1 | 1 # 1 connection with 4 in the middle
正如您希望看到的那样,我希望查询能够“遍历”网络,采用所有可能的路线并省略重复项(例如 1-2-4,这对于 4-2-1 来说是多余的)。我认为我的查询确实满足了这一点...计数就是问题所在。
最佳答案
如果我理解的话,每一行都是 undirected graph 的两点之间的直接连接,并且(根据您的查询)您想要获取具有一跳的两点之间的连接数。我对吗?您可以使用此查询来实现此目的(也许有一个更简单的解决方案,但这个解决方案按指定工作):
select distinct p1, tmp.hop, p2, count from (
select if(p1 < p2, p1, p2) as p1, hop, if(p1 < p2, p2, p1) as p2 from (
select r1.obj_1 as p1, r1.obj_2 as hop, r2.obj_2 as p2
from t_relations r1 inner join t_relations r2 on r1.obj_2 = r2.obj_1
union
select r1.obj_2 as p1, r1.obj_1 as hop, r2.obj_2 as p2
from t_relations r1 inner join t_relations r2 on r1.obj_1 = r2.obj_1
union
select r1.obj_1 as p1, r1.obj_2 as hop, r2.obj_1 as p2
from t_relations r1 inner join t_relations r2 on r1.obj_2 = r2.obj_2
union
select r1.obj_2 as p1, r1.obj_1 as hop, r2.obj_1 as p2
from t_relations r1 inner join t_relations r2 on r1.obj_1 = r2.obj_2
) tmp where p1 <> p2
) tmp inner join (
select hop, count(*) as count from (
select distinct p1, hop, p2 from (
select if(p1 < p2, p1, p2) as p1, hop, if(p1 < p2, p2, p1) as p2 from (
select r1.obj_1 as p1, r1.obj_2 as hop, r2.obj_2 as p2
from t_relations r1 inner join t_relations r2 on r1.obj_2 = r2.obj_1
union
select r1.obj_2 as p1, r1.obj_1 as hop, r2.obj_2 as p2
from t_relations r1 inner join t_relations r2 on r1.obj_1 = r2.obj_1
union
select r1.obj_1 as p1, r1.obj_2 as hop, r2.obj_1 as p2
from t_relations r1 inner join t_relations r2 on r1.obj_2 = r2.obj_2
union
select r1.obj_2 as p1, r1.obj_1 as hop, r2.obj_1 as p2
from t_relations r1 inner join t_relations r2 on r1.obj_1 = r2.obj_2
) tmp where p1 <> p2
) tmp
) tmp group by hop
) tmp2 on tmp.hop = tmp2.hop;
关于MySQL:连接后计算重复项而不进行过滤/分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22974005/