![](/img/trans.png)
[英]SQL: select rows from a certain table based on conditions in this and another table
[英]SQL - Distribute rows from a table into uneven groups, based on another table
假設我有桌子人:
name | group
------------
bob | -
bill | -
joe | -
tim | -
mei | -
jen | -
ben | -
lyn | -
eli | -
fin | -
hal | -
kim | -
和表組:
group | max_people
------------------
A | 2
B | 5
C | 3
如何編寫一個從People表返回行的查詢,每行按順序分配給一個組,直到分配了所有10個人。
分配給組的人數不能超過該組的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 | -
非常感激!
在人員表上創建一個游標
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
首先,你可以像這樣根據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;
你可以在這里看到一個演示
給你的名字編號,例如
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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.