Split the output rows in groups in SQL Server

sql, sql-server

Solution

If you are using SQL 2005 or above, 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 this:

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;

Problem

I have to divide the rows equally, so here, for example, there are 15 rows. I want to divide equally, which is in three groups, but I want the name to come only in front of the first entry of each group, as shown: ``` DECLARE @NAMES TABLE ( [ID] INT IDENTITY, [NAME] VARCHAR(20) ) INSERT INTO @NAMES SELECT 'NAME1' UNION ALL SELECT 'NAME2' UNION ALL SELECT 'NAME3' UNION ALL SELECT 'NAME4' UNION ALL SELECT 'NAME5' UNION ALL SELECT 'NAME6' UNION ALL SELECT 'NAME7' UNION ALL SELECT 'NAME8' UNION ALL SELECT 'NAME9' UNION ALL SELECT 'NAME10' UNION ALL SELECT 'NAME11' UNION ALL SELECT 'NAME12' UNION ALL SELECT 'NAME13' UNION ALL SELECT 'NAME14' UNION ALL SELECT 'NAME15' ``` Desired Output: ``` ID NAME ----------- -------------------- 1 NAME1 2 3 4 5 6 NAME6 7 8 9 10 11 NAME11 12 13 14 15 ```

Original source