MySQL:连接后计算重复项而不进行过滤/分组

标签 mysql sql join count

我希望这不是重复的,我已经搜索了一段时间没有任何有用的结果。

我有一个对象表(带有主键)和一个关系表。每个关系通过外键引用两个对象(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/

相关文章:

mysql - 了解 SQL 别名

mysql - 合并两个 SQL 查询

c# - Insert 语句中的语法不正确

mysql - 如何在 SQL 中操作 select 查询的结果?

t-sql - 您可以在 JOIN w/SQL 上使用 LIKE 运算符进行更新吗?

php - 将数组内爆到 MySQL 查询中

sql - 外键约束-如何删除引用的记录?

sql - 如何将子查询的结果连接到 PostgreSQL 中的表?

MySQL - 合并 2 个表保留所有行

mysql - innodb_log_buffer_size 和 innodb_buffer_pool_size 的区别