You will have to run one query per degree of separation.
I'll assume the following schema (SQLite dialect):
CREATE TABLE person ( id INTEGER NOT NULL, name TEXT, PRIMARY KEY ( id ) ); CREATE TABLE friend ( person INTEGER NOT NULL, friend INTEGER NOT NULL, PRIMARY KEY ( person, friend ) );
Then your graph would be
INSERT INTO person VALUES ( 1, 'Al' ); INSERT INTO person VALUES ( 2, 'Bob' ); INSERT INTO person VALUES ( 3, 'Chuck' ); INSERT INTO person VALUES ( 4, 'Doug' ); INSERT INTO person VALUES ( 5, 'Ed' ); INSERT INTO person VALUES ( 6, 'Frank' ); INSERT INTO person VALUES ( 7, 'Gary' ); INSERT INTO person VALUES ( 8, 'Hamza' ); INSERT INTO person VALUES ( 9, 'Ibrahim' ); INSERT INTO friend VALUES ( 1, 2 ); INSERT INTO friend VALUES ( 1, 3 ); INSERT INTO friend VALUES ( 1, 6 ); INSERT INTO friend VALUES ( 1, 9 ); INSERT INTO friend VALUES ( 2, 1 ); INSERT INTO friend VALUES ( 2, 4 ); INSERT INTO friend VALUES ( 2, 7 ); INSERT INTO friend VALUES ( 3, 1 ); INSERT INTO friend VALUES ( 3, 4 ); INSERT INTO friend VALUES ( 3, 5 ); INSERT INTO friend VALUES ( 3, 6 ); INSERT INTO friend VALUES ( 4, 2 ); INSERT INTO friend VALUES ( 4, 3 ); INSERT INTO friend VALUES ( 4, 8 ); INSERT INTO friend VALUES ( 5, 3 ); INSERT INTO friend VALUES ( 6, 1 ); INSERT INTO friend VALUES ( 6, 3 ); INSERT INTO friend VALUES ( 7, 2 ); INSERT INTO friend VALUES ( 7, 8 ); INSERT INTO friend VALUES ( 7, 9 ); INSERT INTO friend VALUES ( 8, 4 ); INSERT INTO friend VALUES ( 8, 7 ); INSERT INTO friend VALUES ( 9, 1 ); INSERT INTO friend VALUES ( 9, 7 );
With this you can figure out a person's friends by joining the tables:
sqlite> SELECT P1.name, P2.name ...> FROM person P1 ...> JOIN friend F ON P1.id = F.person ...> JOIN person P2 ON F.friend = P2.id ...> WHERE P1.name = 'Bob' ; P1.name|P2.name Bob|Al Bob|Doug Bob|Gary
For the friends' friends you use a subselect:
sqlite> SELECT P1.name, P2.name ...> FROM person P1 ...> JOIN friend F ON P1.id = F.person ...> JOIN person P2 ON F.friend = P2.id ...> WHERE P1.id IN ( ...> SELECT F.friend ...> FROM person P ...> JOIN friend F ON P.id = F.person ...> WHERE P.name = 'Bob' ...> ) ; P1.name|P2.name Al|Bob Al|Chuck Al|Frank Al|Ibrahim Doug|Bob Doug|Chuck Doug|Hamza Gary|Bob Gary|Hamza Gary|Ibrahim
And so on and so forth, analogously:
sqlite> SELECT P1.name, P2.name ...> FROM person P1 ...> JOIN friend F ON P1.id = F.person ...> JOIN person P2 ON F.friend = P2.id ...> WHERE P1.id IN ( ...> SELECT F.friend ...> FROM person P ...> JOIN friend F ON P.id = F.person ...> WHERE P.id IN ( ...> SELECT F.friend ...> FROM person P ...> JOIN friend F ON P.id = F.person ...> WHERE P.name = 'Bob' ...> ) ...> ); Bob|Al Bob|Doug Bob|Gary Chuck|Al Chuck|Doug Chuck|Ed Chuck|Frank Frank|Al Frank|Chuck Hamza|Doug Hamza|Gary Ibrahim|Al Ibrahim|Gary
I used SELECT P1.name, P2.name at the top level SELECT for demonstration purposes. In practice you will want SELECT DISTINCT P2.name.
Makeshifts last the longest.
In reply to Re: sql adjacency list
by Aristotle
in thread sql adjacency list
by boulevard
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |