首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PostgreSQL分配随机的、非重复的值

PostgreSQL分配随机的、非重复的值
EN

Stack Overflow用户
提问于 2020-08-31 16:50:58
回答 1查看 60关注 0票数 1

我有一张桌子上的学生都是这样的:

代码语言:javascript
复制
   firstname    | id 
----------------+----
 Student1       |  1
 Student2       |  2
 Student3       |  3
 Student4       |  4
 Student5       |  5
 Student6       |  6
 Student7       |  7
 Student8       |  8
 Student9       |  9

以及一个包含每个主题要执行的任务数的表,如下所示:

代码语言:javascript
复制
 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

我愿意随意分配任务给学生,但须遵守以下规则:

  • 当任务数量与学生完全相同时,每个学生都应该被随机分配到一个任务号中。
  • 当有比学生更多的任务时,学生的名单应该重复。
  • 当任务少于学生时,任务列表应该重复。
  • 在学生或任务中需要重复的时候,应该随机选择这些任务。

输出可以存储在单独的表中,每个任务一个表。看起来是这样的:

代码语言:javascript
复制
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,也许用另一种编程语言做得更好,但是谢谢您的建议!

EN

回答 1

Stack Overflow用户

发布于 2020-08-31 18:23:20

您可以为您的需求尝试此函数:

代码语言:javascript
复制
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

然后,您可以像下面这样调用上面的函数:

代码语言:javascript
复制
select fun(topicid) from topic;

这将生成具有给定条件的所有表。

演示

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63674961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档