SQL - 根据另一个表将表中的行分配到不均匀的组中

时间:2017-05-29 06:12:54

标签: sql tsql

假设我有表人物:

<div class="procedure-table">
    <table class="table" style="border: 2px slide;">
        <thead>
            <tr>
                <th>Procedure Name</th>
                <th>Cost</th>
                <th>Taxes</th>
                <th>Notes</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td class="proce-td">
                    <ul>
                        <li>
                            <p>Lorem Ipsum is simply dummy text of the printing and typesetting ghj industry.<span><a href="">[+]</a></span>
                            </p>
                        </li>
                    </ul>
                </td>
                <td class="cost-td">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</td>
                <td class="taxes-td">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</td>
                <td>
                    <div class="note-div">Lorem Ipsum is simply dummy text of the printing and typesetting industry.</div>
                    <i class="material-icons close-icon2">close</i>
                    <i class="material-icons edit-icon">edit</i>
                </td>
            </tr>
        </tbody>
    </table>
</div>

表格组:

name | group
------------
bob  | -
bill | -
joe  | -
tim  | -
mei  | -
jen  | -
ben  | -
lyn  | -
eli  | -
fin  | -
hal  | -
kim  | -

如何编写一个从People表返回行的查询,每行按顺序分配给一个组,直到分配了所有10个人。

分配给组的人数不能超过该组的max_people值。因此,如果已达到所有组的最大值,则应保留未分配的剩余人员。

所以输出应该如下:

group | max_people
------------------
A     | 2
B     | 5
C     | 3

非常感谢!

3 个答案:

答案 0 :(得分:1)

在人员表上创建一个游标 DECLARE @name VARCHAR(50),@ groupname varchar(10) DECLARE people_cursor CURSOR FOR SELECT名称 来自人民  打开people_cursor FETCH NEXT FROM people_cursor INTO @name WHILE @@ FETCH_STATUS = 0 开始        从group table中选择top 1 @groupname = group,其中max_people> 0        更新人员设置组= @groupname其中name = @name        更新组设置max_people = max_people -1其中group = @groupname        FETCH NEXT FROM people_cursor INTO @name 结束 关闭people_cursor DEALLOCATE people_cursor

答案 1 :(得分:1)

首先,您可以根据max_people列的值复制组,如下所示

WITH Repeater (Repeat ) AS (
    SELECT 1 AS Repeat UNION ALL
    SELECT Repeat + 1 FROM Repeater WHERE Repeat < 99
),
GroupsRepeat AS (
    SELECT [group], max_people,  ROW_NUMBER() OVER(ORDER BY [group] ASC) AS row_num
    FROM  Groups INNER JOIN Repeater ON Groups.max_people >= Repeater.Repeat    
)

然后,您可以将定义的GroupsRepeat表与People表连接,如下所示

SELECT People.name, 
          COALESCE(GroupsRepeat.[group], People.[group]) AS [group] 
   FROM   (SELECT *, 
                  ROW_NUMBER() OVER(ORDER BY [group]) AS row_num 
           FROM   People) People 
          LEFT JOIN GroupsRepeat 
                 ON GroupsRepeat.row_num = People.row_num; 

您可以看到演示here

答案 2 :(得分:1)

为您的姓名编号,例如

select name, row_number() over (order by name) as num
from names

为您的群组指定号码范围:

select 
  grp, 
  sum(max_people) over (order by grp) - max_people + 1 as from_num,
  sum(max_people) over (order by grp) as till_num
from groups

结合两者:

select n.name, g.grp
from
(
  select name, row_number() over (order by name) as num
  from names
) n
left join 
(
  select 
    grp, 
    sum(max_people) over (order by grp) - max_people + 1 as from_num,
    sum(max_people) over (order by grp) as till_num
  from groups
) g on n.num between g.from_num and g.till_num;