If you are using SQL 2005 or higher, the following should do the job for any number of rows:
declare @numBuckets; select @numBuckets = 3; ;with nameBase as ( select ntile(@numBuckets) over(order by ID) as bucket, NAME, ID from @NAMES ), nameRows as ( select row_number() over(partition by bucket order by ID) as rn, NAME, ID from nameBase ) select n.ID, case when rn = 1 then n.NAME else null end as NAME from nameRows n order by ID;
If you want a solution for SQL 2000 or ANSI, try the following:
declare @numRecs int, @numBuckets int, @recsPerBucket int; select @numRecs = count(*) from @NAMES; select @numBuckets = 3; select @recsPerBucket = @numRecs / @numBuckets; select n.ID, case when d1.minIdInBucket is null then null else n.NAME end as NAME from @NAMES n left join ( select min(n2.ID) as minIdInBucket from ( select n1.ID, n1.NAME, ( select count(*) / @recsPerBucket from @NAMES n2 where n2.ID < n1.ID ) as bucket from @NAMES n1 ) n2 group by n2.bucket ) d1 on n.ID = d1.minIdInBucket order by n.ID;
source share