Nice to meet another C++ programmer. Not that I acutally get to write C++ nowadays, except in my own time for 'fun'.
I delayed answering this because I was hoping that someone else was going to pipe up. Sigh. There are no nice ways to do this. Off the top of my head the only one I can think of is to use correlated subqueries:
Code:
SELECT PersonID,
(SELECT TOP 1 Fruit
FROM HavingFruit
WHERE PersonID = HF.PersonID
ORDER BY Fruit DESC) AS Fruit1,
(SELECT TOP 1 Fruit
FROM (SELECT TOP 2 Fruit
FROM HavingFruit
WHERE PersonID = HF.PersonID
ORDER BY Fruit Desc)
ORDER BY Fruit Asc
) AS Fruit2,
(SELECT TOP 1 Fruit
FROM (SELECT TOP 3 Fruit
FROM HavingFruit
WHERE PersonID = HF.PersonID
ORDER BY Fruit Desc)
ORDER BY Fruit Asc
) AS Fruit3,
(SELECT TOP 1 Fruit
FROM (SELECT TOP 4 Fruit
FROM HavingFruit
WHERE PersonID = HF.PersonID
ORDER BY Fruit Desc)
ORDER BY Fruit Asc
) AS Fruit4
FROM HavingFruit HF
Looks pretty ugly to me and has some problems.
1. Performance. Not only is the resultset basically derived from subqueries, but some of the subqueries use derived tables. Performance will be hideous. If you go down this path make sure have have a clustered index on PersonID and a nonclustered index on Fruit.
2. Scalability. You need to have as many subqueries as you have different types of fruit. This would get hard to maintain.
I tried to think up something creative using CASE, temp tables etc and came up blank.
The only other thing I can think of is that there is an undocumented SQL Server feature that allows you to flatten a resultset into CSV values. There is an example of it here:
http://vyaskn.tripod.com/code/cat.txt
I don't know if it could be adapted to your circumstances. I try to avoid undocumnted features where possible.
regards
David Cameron