我有一张桌子上的学生都是这样的:
firstname | id
----------------+----
Student1 | 1
Student2 | 2
Student3 | 3
Student4 | 4
Student5 | 5
Student6 | 6
Student7 | 7
Student8 | 8
Student9 | 9以及一个包含每个主题要执行的任务数的表,如下所示:
topic | n_tasks
---------+----
1 | 11
2 | 3
3 | 6
4 | 9
5 | 12
6 | 13
7 | 10
8 | 25
9 | 10
10 | 10
11 | 22
12 | 20
14 | 18
15 | 18
16 | 7我愿意随意分配任务给学生,但须遵守以下规则:
输出可以存储在单独的表中,每个任务一个表。看起来是这样的:
table topic1
firstname | task
----------------+----
Student1 | 1
Student8 | 2
Student4 | 3
Student3 | 4
Student7 | 5
Student9 | 6
Student6 | 7
Student7 | 8
Student8 | 9
Student1 | 10
Student2 | 11
table topic2
firstname | task
----------------+----
Student1 | 1
Student2 | 2
Student3 | 3
Student4 | 1
Student5 | 3
Student6 | 2
Student7 | 2
Student8 | 3
Student9 | 1在需要重复任务或学生的情况下,理想情况下,无论是学生还是任务都不会重复,直到所有其他学生或任务都被耗尽为止。
经过思考,我认为这个问题可能不适合PostgreSQL,也许用另一种编程语言做得更好,但是谢谢您的建议!
发布于 2020-08-31 18:23:20
您可以为您的需求尝试此函数:
create or replace function fun(topic_id int) returns bool as
$$
declare
st_count int;
topic_count int;
begin
select count(*) into st_count from student;
select n_tasks into topic_count from topic where topicid=topic_id;
if st_count=topic_count and st_count>0 and topic_count>0 then
execute format('create table %I (first_name varchar, task int)','topic'||topic_id);
execute format('insert into %I select name,row_number() over (order by random()) rn from student','topic'||topic_id);
return true;
end if;
if st_count>topic_count and st_count>0 and topic_count>0 then
execute format('create table %I (first_name varchar, task int)','topic'||topic_id);
execute format('insert into %I
with cte as (select generate_series(1,%s) rn),
cte1 as (
select row_number() over (order by random()) rn,
name from student t1) select t1.name, coalesce(t2.rn,round(random()* %s))
from cte1 t1 left join cte t2 on t1.rn=t2.rn',
'topic'||topic_id,topic_count,topic_count);
return true;
end if;
if st_count<topic_count and st_count>0 and topic_count>0 then
execute format('create table %I (first_name varchar, task int)','topic'||topic_id);
execute format('insert into %I with cte as (select generate_series(1,%s) rn),
cte1 as (select row_number() over (order by random()) rn, name from student t1),
cte2 as (select coalesce(t2.rn, round(random()* %s)) rn_,t1.rn from cte t1
left join cte1 t2 on t1.rn=t2.rn)
select t1.name,t2.rn from cte2 t2 inner join cte1 t1 on t1.rn=t2.rn_',
'topic'||topic_id,topic_count,st_count);
return true;
end if;
return false;
end;
$$
language plpgsql然后,您可以像下面这样调用上面的函数:
select fun(topicid) from topic;这将生成具有给定条件的所有表。
https://stackoverflow.com/questions/63674961
复制相似问题