【问题标题】:MySQL vertices & edges intersectionMySQL 顶点和边的交集
【发布时间】:2012-04-15 13:00:07
【问题描述】:

我有 2 张桌子:edgesusers

edges(有约束:id1

id1
name1
id2
name2

users:

id
name

我想得到一个只有边(id1、name1、id2、name2)的结果集,这样 id1 和 id2 都在 users 表中。这看起来很简单,但我很难得到它。我的尝试:

SELECT
   e.id1 AS id1,
   e.name1 AS name1,
   e.id2 AS id2,
   e.name2 AS name2
FROM 
   edges AS e,
   users AS u
WHERE u.id = e.id1

UNION

SELECT
   e.id1 AS id1,
   e.name1 AS name1,
   e.id2 AS id2,
   e.name2 AS name2
FROM 
   edges AS e,
   users AS u
WHERE u.id = e.id2

任何指针?

【问题讨论】:

    标签: mysql database graph union


    【解决方案1】:

    尝试像这样使用两个 INNER JOINS:

    SELECT * FROM edges e 
    JOIN users u1 ON e.name1 = u1.name 
    JOIN users u2 ON e.name2 = u2.name
    

    【讨论】:

    • 这行得通!这有点慢,但我想第一个 JOIN 是O(|V| * |E|) 操作,所以这些连接在一起会产生O(|V| * |E|^2) 的运行时间?可能是我们在这里能做的最好的事情?
    • 在三个名称字段上创建索引以提高性能。
    • 我不确定,但我认为如果您的 users 表小于 edges 表,您可以先执行 RIGHT JOIN,然后执行 LEFT JOIN,这样会加快查询速度。
    • 所以在这种情况下,我们有一个从每个字段到另一个字段的散列,这意味着我们有 O(1) * O(|V|) 用于第一个连接查找,然后添加另一个 O(|V|) 用于第二个,这意味着共O(|V|)
    【解决方案2】:

    试试这个:

    select e.id1, e.name1, e.id2, e.name2 from edges e
    join users u1 on e.id1 = u1.id
    join users u2 on e.id2 = u2.id
    

    【讨论】:

    • 是的,这是@jordeu 的,但在这里您可以删除重复的列,这是所需要的。我在上面想知道的关于运行时的任何想法?
    【解决方案3】:

    可能是这样的:

    SELECT
       e.id1 AS id1,
       e.name1 AS name1,
       e.id2 AS id2,
       e.name2 AS name2
    FROM 
       edges AS e
    WHERE EXISTS
      (
          SELECT
            NULL
          FROM
            users AS u
          WHERE
            u.id = e.id1
            AND u.id = e.id2
      )
    

    【讨论】:

    • 嗯这返回空集?
    • 没有。它返回有用户的 eges。
    猜你喜欢
    • 1970-01-01
    • 2015-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    相关资源
    最近更新 更多