It took me a little while to figure this out, and it may still need some further tweaking, but this query returns the rows in a phone book format:
declare @data table (ID int, FirstName varchar(20), Surname varchar(20), phone varchar(10))
insert into @data values
(1,'Arthur','Adams',123),
(2,'Betsy','Bloom',456),
(3,'Charles','Crighton',147),
(4,'Derek','Domino',258),
(5,'Eric','Evans',369),
(6,'Frank','Figgs',789),
(7,'Graham','Green',321),
(8,'Harold','Howitzer',654),
(9,'Ian','Imbecile',987),
(10,'Jane','Jerky',741),
(11,'Kathy','Kreme',852),
(12,'Leonard','Lion',963),
(13,'Mike','Mump',159),
(14,'Nigel','Noggin',951),
(15,'Oliver','Owlman',357)
declare @cols int = 3
declare @entriesPerRow int
declare @Reccount int
select @Reccount = COUNT(*) from @data
set @entriesPerRow = case when @Reccount % @cols = 0 then @Reccount / @cols else (@Reccount / @cols)+1 end
select isnull([1],'') as Column1,isnull([2],'') as Column2,isnull([3],'') as Column3,isnull([4],'') as Column4,isnull([5],'') as Column5,isnull([6],'') as Column6
from
(select t.PhoneEntry
, ((rn-1)/@entriesPerRow)+1 as ColNumber
, case when t.rn%@entriesPerRow = 0 then @entriesPerRow else t.rn%@entriesPerRow end as RowNumber
from
( select surname +' ' +firstname +' '+phone as PhoneEntry, row_number() over (order by Surname, Firstname) as rn
from @data) as t)
as p
pivot
(max(PhoneEntry) for ColNumber in ([1], [2], [3], [4],[5],[6])) as pvt
You can add as many columns as you need into the pivot, and it fills however many you've specified in the @cols variable