Search code examples
sqlsql-server-2005master-detail

select the first three details of a master-detail relationship in a view


I have a master detail relationship between a person and its friends:

person

id name
-- ------
 1 Jones
 2 Smith
 3 Norris

friends

id personId friendName
-- -------- ----------
 1        1 Alice
 2        1 Bob
 3        1 Charly
 4        1 Deirdre
 5        2 Elenor

A person can have as many friends as he wants. I want to create a view that selects all persons together with the first three friends it finds; something like this:

id name   friend1 friend2 friend3
-- ----   ------- ------- -------
 1 Jones  Alice   Bob     Charly
 2 Smith  Elenor  <null>  <null>
 3 Norris <null>  <null>  <null>

How do I do this with standard SQL? (Microsoft SQL Server 2005).


Solution

  •     SELECT p.Id, p.name,
                MAX(CASE RowNum
                    WHEN 1 THEN
                     FriendName
                    ELSE
                     NULL
                 END) Friend1,
                MAX(CASE RowNum
                    WHEN 2 THEN
                     FriendName
                    ELSE
                     NULL
                 END) Friend2,
                MAX(CASE RowNum
                    WHEN 3 THEN
                     FriendName
                    ELSE
                     NULL
                 END) Friend3
         FROM   Person p
         LEFT   JOIN (SELECT id, PersonId, FriendName,
                            ROW_NUMBER() OVER(PARTITION BY PersonId ORDER BY id) RowNum
                     FROM   Friends) f
         ON     f.PersonId = p.Id
        GROUP  BY p.Id, p.Name
    

    result:

    1   Jones   Alice   Bob Charly
    3   Norris  NULL    NULL    NULL
    2   Smith   Elenor  NULL    NULL