2011-12-05 75 views
1

我有一個喜歡的表(uid1喜歡uid2),並給出一個特定的用戶ID(uid)我需要找到所有喜歡他的人或任何喜歡他的人,等等等等。遞歸SQL查找喜歡的層次結構(與潛在的圈子)

with recursive Hierarchy(uid, Level) 
as 
(
    select 
     uid1 as uid, 1 as Level 
    from 
    Likes l 
    where 
    l.uid2 = 1 --parameter will go here 
    union all 
    select 
     l.uid1, lh.Level + 1 
    from 
     Likes l 
    inner join Hierarchy lh 
     on l.uid2 = lh.uid 
    where l.uid1 not in (select uid from Hierarchy) --this is wrong syntax in postgresql 
) 

select * from Hierarchy 

當例如給於表以下值喜歡

2,1 (2 likes 1) 
3,1 (3 likes 1) 
4,1 (4 likes 1, 1 is popular) 
3,4 (3 likes 4) 
4,3 (4 likes 3) 

存在喜歡層次了一圈,我想補充的唯一項目不是以前的迭代(因此出現的問題不在))。

那麼是否可以插入一個限制來添加新的uid?

+0

經過短暫的RTFM 我在postgresql文檔中找到了解釋 http://www.postgresql.org/docs/8.4/static/queries-with.html – Bg1987

+1

如果您有解決方案,請將其作爲回答,不要只參考文檔。 –

+0

究竟是什麼問題,你想要一個「約束」來禁止循環引用?可以在插入時完成。也可以作爲一種限制,但可能需要額外的金絲雀桌。 – wildplasser

回答

1

基於此模板:

WITH RECURSIVE search_graph(id, link, data, depth, path, cycle) AS (
     SELECT g.id, g.link, g.data, 1, 
      ARRAY[g.id], 
      false 
     FROM graph g 
     UNION ALL 
     SELECT g.id, g.link, g.data, sg.depth + 1, 
      path || g.id, 
      g.id = ANY(path) 
     FROM graph g, search_graph sg 
     WHERE g.id = sg.link AND NOT cycle 
) 
SELECT * FROM search_graph; 

(http://www.postgresql.org/docs/8.4/static/queries-with.html)

你:

with recursive Hierarchy(uid, Level, path, cycle) 
as 
(
    select 
     uid1 as uid, 1 as Level, ARRAY[l.uid], false 
    from 
    Likes l 
    where 
    l.uid2 = 1 --parameter will go here 
    union all 
    select 
     l.uid1, lh.Level + 1, 
     path || l.uid, 
     l.uid = ANY(path) 
    from 
     Likes l 
    inner join Hierarchy lh 
     on l.uid2 = lh.uid 
) 

select * from Hierarchy