2016-11-08 23 views
0

这里是我的表的所需输出。只要每个组中不超过3个SegmentType并且每个组不超过15个记录,则EmpID和SegmentType的顺序无关紧要。每组3段,每组不超过15行

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 
+0

你能展示预期的产出吗? –

+0

嗨,欢迎来到SO。我们需要从您那里得到更多信息,才能真正提供帮助。这是一个很好的开始。 http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/ –

+0

它看起来好像你需要添加一个Partition By语句你的行号,那么你可以指出'RowNumber <= 15'的位置。 –

回答

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