Рекурсивный SQL для поиска иерархии лайков (с потенциальными кругами) - PullRequest
1 голос
/ 05 декабря 2011

У меня есть таблица лайков (uid1 лайки uid2) и заданный конкретный идентификатор пользователя (uid). Мне нужно найти всех людей, которые ему нравятся, или всех, кто любит его, и так далее, и так далее.

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

проблема возникает, когда, например, с учетом следующих значений в таблице Likes

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)

есть круг в иерархии лайков, и я хотел добавить только элементы, не являющиеся предыдущимиитерация (следовательно, NOT IN).

Так можно ли вставить ограничение только для добавления новых идентификаторов?

1 Ответ

1 голос
/ 05 декабря 2011

На основе этого шаблона:

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
...