views:

338

answers:

2

Let's say that we have we have a table with the classic 'manager id' recursive relationship:

Users user_id int manager_id int (refers to user_id)

If you randomly select 2 rows in the table- or 2 nodes- how do you find the lowest level, common ancestor? My platform is SQL Server 2005 (Transact-SQL) but any ANSI compliant SQL will also work...

+2  A: 
WITH
    hier1 (id, parent) AS (
    SELECT id, parent
    FROM table l
    WHERE id = @user1
    UNION ALL
    SELECT id, parent
    FROM table l, hier1 h
    WHERE l.id = parent
    ),
    hier2 (id, parent) AS (
    SELECT id, parent
    FROM table l
    WHERE id = @user2
    UNION ALL
    SELECT id, parent
    FROM table l, hier1 h
    WHERE l.id = parent
    ),
SELECT  TOP 1 hier1.id
FROM    hier1, hier2
WHERE   hier1.id = hier2.id
Quassnoi
+3  A: 

A few minor edits to Quassnoi's answer, and it works:

WITH
    hier1 (id, parent) AS (
    SELECT      id, parent
    FROM        table
    WHERE       id = @user1
    UNION ALL
    SELECT      id, parent
    FROM        table l, hier1 h
    WHERE       l.id = h.parent
    ),
    hier2 (id, parent) AS (
    SELECT      id, parent
    FROM        table
    WHERE       id = @user2
    UNION ALL
    SELECT      id, parent
    FROM        table l, hier1 h
    WHERE       l.id = h.parent
    )
SELECT  TOP 1 hier1.id
FROM    hier1, hier2
WHERE   hier1.id = hier2.id
What were the edits? I don't see any difference :)
Quassnoi
h.parent, before selectvery minor :) thanks for the original answer