每个细分3组和1组每组不超过15行

时间:2016-11-08 20:32:13

标签: sql sql-server tsql

这是我表的理想输出。只要每个组不超过3个SegmentType且每个组不超过15个记录,EmpID和SegmentType的顺序无关紧要。

    EmpID | WorkSegment | Group(What I'm trying to update)  |
    ------| ----------- | --------------------------------- |
    123   |  yard       | 1                                 |
    245   |  yard       | 1                                 |
    478   |  yard       | 1                                 |
    584   |  remote     | 1                                 |
    321   |  remote     | 1                                 |
    879   |  remote     | 1                                 |
    747   |  office     | 1                                 |
    412   |  office     | 1                                 |
    251   |  office     | 1                                 |
    755   | support     | 1                                 |
    963   | support     | 1                                 |
    369   | support     | 1                                 |
    977   | intern      | 1                                 |
    888   | intern      | 1                                 |
    552   | intern      | 1                                 |
    225   | sales       | 2                                 |
    332   | sales       | 2                                 |
    357   | sales       | 2                                 |
    753   | yard        | 2                                 |

这是我到目前为止的代码。这实现了每组不超过3个WorkSegments的第一个目标,但现在我需要为每个组添加仅15行的限制。有什么想法吗?

--Create table of distinct SegmentType
Select  distinct SegmentType 
into    Work_DistinctSegmentTypes
from    Work_AllData

Alter   table Work_DistinctSegmentTypes
Add     RowID INT IDENTITY(1, 1) NOT NULL


--Procedure to update group column
DECLARE @CurrentRowID INT,
        @MaxRowID INT,
        @SegmentType varchar(50)

SET @CurrentRowID = 1
SET @MaxRowID = (Select max(rowID) from Work_DistinctSegmentTypes)


WHILE @CurrentRowID <= @MaxRowID

BEGIN
    Set @SegmentType = (Select SegmentType from Work_DistinctSegmentTypes Where RowID = @CurrentRowID)

    Update  Work_AllData  
    SET     [Group] =(RowNum - (1)) / 3 + 1  
    FROM        (SELECT EmpID,ROW_NUMBER() OVER (ORDER BY EmpID) AS RowNum 
            FROM    Work_AllData 
            Where   SegmentType = @SegmentType) st, Work_AllData 
            Where   st.EmpID = Work_AllData.EmpID

SET @CurrentRowID = @CurrentRowID + 1 


END

1 个答案:

答案 0 :(得分:0)

递归CTE可以提供您想要的分组间隔。

如果您还没有标识列,则需要在Work_AllData表中添加标识列。

alter table Work_AllData
add RowID int identity(1, 1)

然后您可以定义间隔并设置递归CTE。

declare @maxGroupMembers int = 15  --max number of members per group

declare @countEmployees int
select @countEmployees = max(WAD.RowID)  --count of employees
from Work_AllData WAD

;with baseSet as (
    select 1 groupMember,
         1 RowID,
         1 [Group]

     union all

     select case
             when BS.groupMember = @maxGroupMembers  --When max number of members per group is met
                 then 1  --reset counter
             else BS.groupMember + 1  --otherwise keep counting up members in group
         end groupMember,
         BS.RowID + 1 RowID,  --cycle through employees by a increment of 1
         case
             when BS.groupMember = @maxGroupMembers  --When max number of members per group is met
                 then BS.[Group] + 1  --skip to the next group
             else BS.[Group]  --otherwise assign members to current group
         end [Group]
    from baseSet BS  --Apply against results of current CTE
    where BS.RowID < @countEmployees)  --Stop Recursion at max number of employees
update WAD
set WAD.[Group] = BS.[Group]  --Update member group 
from Work_AllData WAD
join baseSet BS
    on WAD.RowID = BS.RowID  --by employee identity column

Option (maxrecursion 200)  --must be manually set high enough to include all employees