我希望这不是重复,我搜索了一段时间没有任何有用的结果。
我有一个对象表(带有主键)和一个关系表。每个关系通过外键(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
现在,我的问题是我希望看到每个跃点的连接数量,但是没有过滤(我需要选择所有行,因此group by不是一个选项)。我怎么能这样做?
根据要求,提供一些示例数据。为简单起见,我假设t_relations中的数字是实际对象。
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的冗余)。我认为我的查询确实实现了这一点......计数就是问题。
答案 0 :(得分: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;