views:

13

answers:

1

I have the adjacency list of a large graph stored in a table.

v1 |  v2
1  |  2
1  |  3
1  |  4
2  |  5
3  |  5
3  |  6
4  |  7
7  |  9
5  |  10

I am trying to extract the graph 2-hops away from say vertex 1 so that it returns all the edges from the above list except (7,9) and (5,10). I managed this:

SELECT * FROM stub_graph WHERE v1 IN (SELECT v1 FROM stub_graph WHERE v1=1 UNION select v2 FROM stub_graph WHERE v1=1) ;

I am not particularly happy with my solution because of two reasons:

  1. Presence of IN
  2. This is able to extract links such as 1-2 and 2-5 but am not able to extract links such as 6-7.

Is there a good way to do this?

Just in case someone is interested in creating the table, here's the sql code:

create table stub_graph(v1 int(11), v2 int(11));
insert into stub_graph VALUES(1,2);
insert into stub_graph VALUES(1,3);
insert into stub_graph VALUES(1,4);
insert into stub_graph VALUES(2,5);
insert into stub_graph VALUES(3,5);
insert into stub_graph VALUES(3,6);
insert into stub_graph VALUES(4,7);
insert into stub_graph VALUES(6,7);
insert into stub_graph VALUES(7,9);
insert into stub_graph VALUES(5,10);
A: 

Try this:

SELECT g1.v1 as Root, g2.v1 as Next g3.v1 as Final FROM stub_graph g1 
  LEFT JOIN stub_graph g2 on g2.v1 = g1.v2
  LEFT JOIN stub_graph g3 on g3.v1 = g2.v2
WHERE g1.v1 = 1

If you want (6-7) though you need to go three levels deep as it is 3 hops away from 1 (1-3, 3-6, 6-7).

If you want to go arbitrarily deep you will need to look at a recursive stored proc which I think the later versions of MySQL support, but this looks suitable for your needs. Alternatively the link below has some other ideas.

That should yield:

Root | Next | Final
   1 |    3 |     5
   1 |    3 |     6
   1 |    2 |     5
   1 |    4 |     7

See also this link on Hierarchical Data

Graphain