• 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