使用 SQL 查找节点的邻居

问题描述 投票:0回答:1

我在 SQL 中有下表:

CREATE TABLE friendships 
(
    id INT PRIMARY KEY,
    person VARCHAR(50),
    friend VARCHAR(50)
);

INSERT INTO friendships (id, person, friend) VALUES
(1, 'person3', 'person9'),
(3, 'person10', 'person4'),
(4, 'person2', 'person1'),
(5, 'person6', 'person7'),
(7, 'person4', 'person10'),
(8, 'person6', 'person7'),
(10, 'person10', 'person9'),
(11, 'person5', 'person10'),
(12, 'person3', 'person7'),
(13, 'person9', 'person5'),
(14, 'person9', 'person7'),
(15, 'person9', 'person5'),
(16, 'person3', 'person6'),
(17, 'person8', 'person9'),
(18, 'person10', 'person2'),
(19, 'person7', 'person5'),
(20, 'person10', 'person8');

使用 R,我可以绘制表格数据,如下所示:

library(igraph)

friendships = structure(list(person = c("person3", "person10", "person2", "person6", 
"person4", "person6", "person10", "person5", "person3", "person9", 
"person9", "person9", "person3", "person8", "person10", "person7", 
"person10"), friend = c("person9", "person4", "person1", "person7", 
"person10", "person7", "person9", "person10", "person7", "person5", 
"person7", "person5", "person6", "person9", "person2", "person5", 
"person8")), row.names = c(1L, 3L, 4L, 5L, 7L, 8L, 10L, 11L, 
12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L), class = "data.frame")


g <- graph_from_data_frame(df, directed = FALSE)
plot(g, vertex.size=10, vertex.label.cex=0.8)

仅使用SQL命令,我想回答以下问题(将来,泛化到n级):

  • 有多少个节点通过 Degree2 连接到 Person10(即朋友的朋友,8 个人)
  • 与 person10 存在 2 级关联的人是谁? (即人物2,人物1,人物4,人物8,人物9,人物5,人物7,人物3)

我不确定如何在 SQL 中执行这些操作 - 我通常使用 igraph 来解决这些问题。

这是我尝试回答第一个问题:

SELECT COUNT(DISTINCT f2.friend)
FROM friendships f1
JOIN friendships f2 ON f1.friend = f2.person
WHERE f1.person = 'person10' AND f2.friend != 'person10' AND f2.friend NOT IN (
    SELECT friend FROM friendships WHERE person = 'person10'
);

#result
 3

这是我尝试回答第二个问题:

SELECT DISTINCT f2.friend
FROM friendships f1
JOIN friendships f2 ON f1.friend = f2.person
WHERE f1.person = 'person10' AND f2.friend != 'person10' AND f2.friend NOT IN (
    SELECT friend FROM friendships WHERE person = 'person10'
);

#result
1 person5
2 person7
3 person1

然而,这些并不是正确的结果。

有人可以告诉我如何正确执行此操作吗?

谢谢!

sql r netezza
1个回答
0
投票

考虑这个递归示例

with t0 as (
select person,friend
from friendships
-- where person='person10'
  union
select friend,person
from friendships
-- where friend='person10'
)
, r as(
select person,friend,1 lvl
  ,cast(concat(person,'-',friend) as varchar(1000))path
from t0
union all
select r.person,t.friend ,r.lvl+1 lvl
  ,cast(concat(path,'-',t.friend) as varchar(1000)) path
from r
inner join friendships t on (t.person=r.friend and t.friend<>r.person)
where lvl<2
union all
select r.person,t.person ,r.lvl+1 lvl
  ,cast(concat(path,'-',t.person)  as varchar(1000))path
from r
inner join friendships t on (t.friend=r.friend and t.person<>r.person)
where lvl<2
)
,allfriends as (
select person,friend ,count(*) qty
from r
group by person,friend
)
-- select * from r order by lvl,friend;
-- select * from allfriends;
select person,count(*)friend_qty
from allfriends
group by person
© www.soinside.com 2019 - 2024. All rights reserved.