sqlsql-serverhierarchyhierarchical-data

Query to find all members of multi level many to many relationships and also the top most member of the hierarchy


Multiple student can go to 1 teacher, but 1 student can't go to multiple teacher. There is no limit of level in this teacher student hierarchy.

How using a single SQL query in SQL Server we can get the following for any student
a) top teacher
b) all student teacher linked to that student


Solution

  • As your "linked student teacher Ids" is the same for every student under a given head teacher, you'll probably want to compute that list once per head teacher (instead of computing it as many times as you have students).

    Then a Common Table Expression will allow you to:

    From the point of view of the database, this is only one query (think "subqueries written sequentially").

    with
      -- h (Hierarchy) is computed recursively. Each step gets its level (which will help order the groups later)
      h as
      (
        -- Head teachers are those who are not student either.
        select distinct TeacherId as id, TeacherId as HeadTeacherId, 0 hlevel from t where not exists (select 1 from t UberTeacher where t.TeacherId = UberTeacher.StudentId)
        union all
        select StudentId, HeadTeacherId, hlevel + 1
        from h join t on t.TeacherId = h.id
      ),
      -- Now compute the whole group only once per head teacher.
      heads as
      (
        select HeadTeacherId id, string_agg(id, ',') within group (order by hlevel desc, id desc) WholeGroup
        from h
        group by HeadTeacherId
      )
    -- Finally each student gets a copy of its head teacher's list.
    select h.id, HeadTeacherId, WholeGroup
    from h join heads on h.HeadTeacherId = heads.id;
    

    This gives the exact result you are looking for.