2017-05-29 4 views
1

を行を配布します。SQL - 私はテーブルの人々を持っていると仮定し、別のテーブルに基づいて、不均一なグループにテーブルから

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

とテーブルグループ:

私はそのクエリを記述しますどのように
group | max_people 
------------------ 
A  | 2 
B  | 5 
C  | 3 

すべての10人が割り当てられるまで、グループに順番に割り当てられた行がPeopleテーブルから返されます。

グループに割り当てられた人数は、そのグループのmax_people値を超えることはできません。したがって、グループのすべての最大値に達した場合、残っている人は未割り当てのままにしておく必要があります。

ので、出力は次のようになります。

感謝
name | group 
------------ 
bob | A 
bill | A 
joe | B 
tim | B 
mei | B 
jen | B 
ben | B 
lyn | C 
eli | C 
fin | C 
hal | - 
kim | - 

+1

テーブルはその行に順序を持っていません。では、「逐次」とはどういう意味ですか? – philipxy

答えて

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 

コンバイン2:

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

すべての答えが働いていましたが、これは最も簡単で最も単純な方法でした。ありがとう! –

1

あなたは人々のテーブルのように定義されたGroupsRepeatテーブルに参加することができ、あなたはその後、この

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  
) 

ようmax_people列の値でグループベースを複製することができ、

DECLARE @name VARCHAR(50),@groupname varchar(10) 

DECLARE people_cursor CURSOR FOR 
SELECT name 
FROM people 
OPEN people_cursor 
FETCH NEXT FROM people_cursor INTO @name 

WHILE @@FETCH_STATUS = 0 
BEGIN 
     select top 1 @groupname = group from groups table where max_people>0 
     update people set group = @groupname where name = @name 

     update group set max_people= max_people -1 where group = @groupname 

     FETCH NEXT FROM people_cursor INTO @name 
END 

CLOSE people_cursor 
DEALLOCATE people_cursor 
1

まず人々のテーブルの上にカーソルを作成します。以下は

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

関連する問題