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).
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
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
精彩评论