выберите первые три детали отношения мастер-деталь в представлении - PullRequest
1 голос
/ 06 сентября 2010

У меня есть мастер детализация отношений между человеком и его друзьями:

человек

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

Друзья

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

У человека может быть столько друзей, сколько он хочет. Я хочу создать представление, которое выбирает всех людей вместе с первыми тремя друзьями, которых он находит; как то так:

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

Как мне сделать это со стандартным SQL? (Microsoft SQL Server 2005).

Ответы [ 2 ]

2 голосов
/ 06 сентября 2010
    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

результат:

1   Jones   Alice   Bob Charly
3   Norris  NULL    NULL    NULL
2   Smith   Elenor  NULL    NULL
0 голосов
/ 17 июля 2013
SELECT t1.id, t1.name,
  (SELECT max(friendname)
   FROM friends t2
   WHERE t2.personid = t1.id)
  "Friend1",
  (SELECT max(friendname)
   FROM friends t2
   WHERE friendname < (SELECT max(friendname)
                       FROM friends t3
                       WHERE t3.personid = t1.id)
   AND t2.personid = t1.id)
  "Friend2",
  (SELECT max(friendname)
   FROM friends t2
   WHERE friendname < (SELECT max(friendname)
                       FROM friends t3
                       WHERE friendname < (SELECT max(friendname)
                                           FROM friends t4
                                           WHERE t4.personid = t1.id)
                       AND t3.personid = t1.id)
   AND t2.personid = t1.id)
  "Friend3"
FROM person t1
...