我如何修改我的 SQL 声明,以便每个项目都有 (x) 名评委,并且每个评委在他们的人口中平均参与?
How do I modify my SQL Statement so each Project has (x) Judges and each Judge participates evenly among their population?
问题
如何修改我的 SQL 声明,使每个项目有 4 名独特的评委,并且每个评委平均评判分配给他们的部门和类别的相同数量的项目?
要求
Population Project 需要Population Judge 审核(x) 次。
x = 4
- 每个项目都按部门和类别分组。
每位评委按部门和类别分组。
每个项目必须由 (x) 位独特的评委审核。
- 每位评委不得对同一个项目进行两次评审。
- 每位评委都应分配到与其所在部门和类别分组中的其他评委相同数量的项目进行评审。
样本源判断Table
create table judges(judge_id, division, category) as (
select 68, 'Elementary', 'ANY' from dual union all
select 19, 'Elementary', 'ANY' from dual union all
select 22, 'Elementary', 'ANY' from dual union all
select 32, 'Elementary', 'ANY' from dual union all
select 33, 'Elementary', 'ANY' from dual union all
select 37, 'Elementary', 'ANY' from dual union all
select 38, 'Elementary', 'ANY' from dual union all
select 40, 'Elementary', 'ANY' from dual union all
select 47, 'Elementary', 'ANY' from dual union all
select 62, 'Elementary', 'ANY' from dual union all
select 63, 'Elementary', 'ANY' from dual union all
select 13, 'Elementary', 'ANY' from dual union all
select 36, 'Elementary', 'ANY' from dual union all
select 55, 'Elementary', 'ANY' from dual union all
select 59, 'Elementary', 'ANY' from dual union all
select 60, 'Elementary', 'ANY' from dual union all
select 9, 'Junior', 'EC' from dual union all
select 10, 'Junior', 'EC' from dual union all
select 48, 'Junior', 'EC' from dual union all
select 11, 'Junior', 'LS' from dual union all
select 21, 'Junior', 'LS' from dual union all
select 23, 'Junior', 'LS' from dual union all
select 26, 'Junior', 'LS' from dual union all
select 31, 'Junior', 'LS' from dual union all
select 80, 'Junior', 'LS' from dual union all
select 14, 'Junior', 'PE' from dual union all
select 15, 'Junior', 'PE' from dual union all
select 24, 'Junior', 'PE' from dual union all
select 29, 'Junior', 'PE' from dual union all
select 30, 'Junior', 'PE' from dual union all
select 43, 'Junior', 'PE' from dual union all
select 53, 'Junior', 'PE' from dual union all
select 56, 'Junior', 'PE' from dual union all
select 57, 'Junior', 'PE' from dual union all
select 58, 'Junior', 'PE' from dual union all
select 65, 'Junior', 'PE' from dual union all
select 67, 'Junior', 'PE' from dual union all
select 69, 'Junior', 'PE' from dual union all
select 8, 'Senior', 'ANY' from dual union all
select 18, 'Senior', 'ANY' from dual union all
select 20, 'Senior', 'ANY' from dual union all
select 35, 'Senior', 'ANY' from dual union all
select 66, 'Senior', 'ANY' from dual union all
select 39, 'Senior', 'ANY' from dual union all
select 70, 'Senior', 'ANY' from dual union all
select 71, 'Senior', 'ANY' from dual union all
select 74, 'Senior', 'ANY' from dual union all
select 6, 'Senior', 'ANY' from dual union all
select 44, 'Senior', 'ANY' from dual union all
select 45, 'Senior', 'ANY' from dual union all
select 49, 'Senior', 'ANY' from dual union all
select 61, 'Senior', 'ANY' from dual union all
select 64, 'Senior', 'ANY' from dual union all
select 72, 'Senior', 'ANY' from dual union all
select 75, 'Senior', 'ANY' from dual union all
select 79, 'Senior', 'ANY' from dual union all
select 82, 'Senior', 'ANY' from dual
);
示例源项目Table
create table projects(project_id, division, category) as (
select 39, 'Elementary', 'ANY' from dual union all
select 40, 'Elementary', 'ANY' from dual union all
select 47, 'Elementary', 'ANY' from dual union all
select 48, 'Elementary', 'ANY' from dual union all
select 56, 'Elementary', 'ANY' from dual union all
select 57, 'Elementary', 'ANY' from dual union all
select 58, 'Elementary', 'ANY' from dual union all
select 60, 'Elementary', 'ANY' from dual union all
select 65, 'Elementary', 'ANY' from dual union all
select 66, 'Elementary', 'ANY' from dual union all
select 93, 'Elementary', 'ANY' from dual union all
select 94, 'Elementary', 'ANY' from dual union all
select 97, 'Elementary', 'ANY' from dual union all
select 104, 'Elementary', 'ANY' from dual union all
select 105, 'Elementary', 'ANY' from dual union all
select 107, 'Elementary', 'ANY' from dual union all
select 110, 'Elementary', 'ANY' from dual union all
select 112, 'Elementary', 'ANY' from dual union all
select 114, 'Elementary', 'ANY' from dual union all
select 117, 'Elementary', 'ANY' from dual union all
select 120, 'Elementary', 'ANY' from dual union all
select 121, 'Elementary', 'ANY' from dual union all
select 123, 'Elementary', 'ANY' from dual union all
select 124, 'Elementary', 'ANY' from dual union all
select 126, 'Elementary', 'ANY' from dual union all
select 127, 'Elementary', 'ANY' from dual union all
select 128, 'Elementary', 'ANY' from dual union all
select 133, 'Elementary', 'ANY' from dual union all
select 134, 'Elementary', 'ANY' from dual union all
select 136, 'Elementary', 'ANY' from dual union all
select 140, 'Elementary', 'ANY' from dual union all
select 142, 'Elementary', 'ANY' from dual union all
select 152, 'Elementary', 'ANY' from dual union all
select 153, 'Elementary', 'ANY' from dual union all
select 162, 'Elementary', 'ANY' from dual union all
select 167, 'Elementary', 'ANY' from dual union all
select 173, 'Elementary', 'ANY' from dual union all
select 174, 'Elementary', 'ANY' from dual union all
select 188, 'Elementary', 'ANY' from dual union all
select 27, 'Junior', 'EC' from dual union all
select 67, 'Junior', 'EC' from dual union all
select 82, 'Junior', 'EC' from dual union all
select 83, 'Junior', 'EC' from dual union all
select 99, 'Junior', 'EC' from dual union all
select 113, 'Junior', 'EC' from dual union all
select 115, 'Junior', 'EC' from dual union all
select 149, 'Junior', 'EC' from dual union all
select 164, 'Junior', 'EC' from dual union all
select 169, 'Junior', 'EC' from dual union all
select 185, 'Junior', 'EC' from dual union all
select 189, 'Junior', 'EC' from dual union all
select 18, 'Junior', 'LS' from dual union all
select 19, 'Junior', 'LS' from dual union all
select 20, 'Junior', 'LS' from dual union all
select 21, 'Junior', 'LS' from dual union all
select 23, 'Junior', 'LS' from dual union all
select 24, 'Junior', 'LS' from dual union all
select 26, 'Junior', 'LS' from dual union all
select 28, 'Junior', 'LS' from dual union all
select 29, 'Junior', 'LS' from dual union all
select 30, 'Junior', 'LS' from dual union all
select 78, 'Junior', 'LS' from dual union all
select 80, 'Junior', 'LS' from dual union all
select 90, 'Junior', 'LS' from dual union all
select 91, 'Junior', 'LS' from dual union all
select 106, 'Junior', 'LS' from dual union all
select 144, 'Junior', 'LS' from dual union all
select 150, 'Junior', 'LS' from dual union all
select 151, 'Junior', 'LS' from dual union all
select 156, 'Junior', 'LS' from dual union all
select 157, 'Junior', 'LS' from dual union all
select 159, 'Junior', 'LS' from dual union all
select 161, 'Junior', 'LS' from dual union all
select 165, 'Junior', 'LS' from dual union all
select 166, 'Junior', 'LS' from dual union all
select 168, 'Junior', 'LS' from dual union all
select 178, 'Junior', 'LS' from dual union all
select 180, 'Junior', 'LS' from dual union all
select 187, 'Junior', 'LS' from dual union all
select 22, 'Junior', 'PE' from dual union all
select 59, 'Junior', 'PE' from dual union all
select 61, 'Junior', 'PE' from dual union all
select 74, 'Junior', 'PE' from dual union all
select 81, 'Junior', 'PE' from dual union all
select 95, 'Junior', 'PE' from dual union all
select 96, 'Junior', 'PE' from dual union all
select 116, 'Junior', 'PE' from dual union all
select 145, 'Junior', 'PE' from dual union all
select 148, 'Junior', 'PE' from dual union all
select 158, 'Junior', 'PE' from dual union all
select 160, 'Junior', 'PE' from dual union all
select 172, 'Junior', 'PE' from dual union all
select 176, 'Junior', 'PE' from dual union all
select 181, 'Junior', 'PE' from dual union all
select 186, 'Junior', 'PE' from dual union all
select 14, 'Senior', 'ANY' from dual union all
select 15, 'Senior', 'ANY' from dual union all
select 42, 'Senior', 'ANY' from dual union all
select 43, 'Senior', 'ANY' from dual union all
select 44, 'Senior', 'ANY' from dual union all
select 45, 'Senior', 'ANY' from dual union all
select 46, 'Senior', 'ANY' from dual union all
select 49, 'Senior', 'ANY' from dual union all
select 51, 'Senior', 'ANY' from dual union all
select 52, 'Senior', 'ANY' from dual union all
select 53, 'Senior', 'ANY' from dual union all
select 54, 'Senior', 'ANY' from dual union all
select 75, 'Senior', 'ANY' from dual union all
select 76, 'Senior', 'ANY' from dual union all
select 77, 'Senior', 'ANY' from dual union all
select 92, 'Senior', 'ANY' from dual union all
select 108, 'Senior', 'ANY' from dual union all
select 118, 'Senior', 'ANY' from dual union all
select 119, 'Senior', 'ANY' from dual union all
select 125, 'Senior', 'ANY' from dual union all
select 131, 'Senior', 'ANY' from dual union all
select 132, 'Senior', 'ANY' from dual union all
select 135, 'Senior', 'ANY' from dual union all
select 137, 'Senior', 'ANY' from dual union all
select 138, 'Senior', 'ANY' from dual union all
select 139, 'Senior', 'ANY' from dual union all
select 141, 'Senior', 'ANY' from dual union all
select 143, 'Senior', 'ANY' from dual union all
select 146, 'Senior', 'ANY' from dual union all
select 154, 'Senior', 'ANY' from dual union all
select 171, 'Senior', 'ANY' from dual
);
甲骨文SQL代码
select
project_id
,division
,category
,judge_id
,best_match
from(
select
project.project_id
,project.division
,project.category
,judge.judge_id
,row_number() over(
partition by project.project_id
order by dbms_random.value
) as best_match
from frsf_fair.project_division_category project
left join (
select
judge_id
,division
,category
,row_number() over(
partition by division
order by dbms_random.value
) as r
from frsf_fair.judge_division_category
) judge on project.division = judge.division
and project.category = judge.category
) assignment
where best_match <= 4
数据输出示例
PROJECT_ID DIVISION CATEGORY JUDGE_ID BEST_MATCH
14 Senior ANY 72 1
14 Senior ANY 74 2
14 Senior ANY 20 3
14 Senior ANY 44 4
15 Senior ANY 79 1
15 Senior ANY 39 2
15 Senior ANY 75 3
15 Senior ANY 20 4
18 Junior LS 23 1
18 Junior LS 31 2
18 Junior LS 26 3
18 Junior LS 21 4
问题
count(*)/projects 的数量应该平均分配给裁判组的 Division 和 Category。相反,一些法官被分配到 20 个项目,而其他人被分配到很少的项目。我不知道如何修改我的查询,因此每个评委必须在项目部门和类别分组中引用相同次数。我要确保平等参与。
JUDGE_ID COUNT(*)
64 8
72 16
23 20
57 4
14 4
6 4
58 9
我能做的最好的就是这个查询:
with
t as (select judge_id jid, project_id pid, category cat, division div,
dense_rank() over (order by project_id) rp,
dense_rank() over (order by judge_id) rj,
count(1) over (partition by project_id) cnt
from judges join projects using (division, category)),
c(pid, jid, cat, div, rn, rp) as (
select pid, jid, cat, div, 1, rp from t where mod(rp, cnt) = mod(rj, cnt)
union all
select c.pid, t.jid, c.cat, c.div, rn + 1, c.rp
from c join t on c.rp = t.rp and c.jid <> t.jid
and mod(t.rp, t.cnt) = mod(t.rj + c.rn, t.cnt)
where rn < 3)
select * from c
它有什么作用?首先使用添加的行号和计数(rp、rj、cnt)进行基本连接。然后 mod()
使用这些列来连接锚查询 where mod(rp, cnt) = mod(rj, cnt)
中的行。然后是递归部分,只为每个项目添加所需数量的评委。也许有人不用递归就可以做到,但我做不到。您可以通过将随机 id
s 分配给判断并在查询中使用它们而不是真正的 id
s 来稍微随机化输出。将 3
替换为所需的评论数。
此 dbfiddle 显示 5 个项目、5 个评委、每个项目 3 个评论。评委不重复,均分。
编辑: 这是更正的基本查询:
with t as (
select category, division, project_id, judge_id,
dense_rank() over (partition by category, division
order by project_id) rp,
dense_rank() over (partition by category, division, project_id
order by judge_id) rj,
count(1) over (partition by project_id) cnt
from projects join judges using (category, division) )
select * from t
join (select level lvl from dual connect by level <= 3)
on mod(rj, cnt) = mod((rp -1) * 3 + lvl, cnt)
我检查了项目的结果(按 project_id 分组),每个项目都有 3 位不同的评委。
我检查了法官的结果(按类别、部门分组,judge_id),他的 class 中的每个法官都有相同数量的案件(如果没有足够的项目进行平均分配,则相差一个)。
逻辑与我的第一个查询相同。正如我所说,您可以先随机分配评委:
select row_number() over (order by dbms_random.value) rnd_jdg_id, judges.* from judges
并在主查询中使用这个假 ID 作为输入以获得完全随机分配。
我想到了一个利用我的 Oracle 数据库中的过程的解决方案。
我的方法是遍历每个项目 ID。
在我的循环中,它会将 1 循环到我需要的分配数量,在本例中为 4。
我们需要从法官列表中抽取一个随机法官 ID,方法是按升序计算他们已经分配了多少任务。我想先用最少的赋值。
他们的分配数如果增加+1
我们更新最终列表中的值table
我们循环直到给出项目分配的数量,然后评估下一个项目。
创建或替换过程 random_judge_project_list 为
assign_count number := 0;
next_count number := 1;
assignments number := 4;
jid number;
sql_stmt varchar2(4000);
location varchar2(20);
开始
execute immediate 'truncate table judge_project_list';
execute immediate 'update judge_assignment_count set assignment_count = 0';
/*We First Need to Loop through Each Project*/
for project in (
select
project_id
,division
,category as source_category
,case division
when 'Junior' then category
else 'ANY'
end as category
from projects a
order by division asc, category asc
)
loop
/*While Looping we then need to assign judges randomly*/
for assign in 1 .. assignments
loop
select judge_id
into jid
from(
select *
from judge_assignment_count
where division = project.division
and judge_id not in (select judge_id from judge_project_list where project_id = project.project_id)
order by assignment_count asc, dbms_random.random asc
) where rownum = 1
;
select assignment_count
into assign_count
from judge_assignment_count
where judge_id = jid
and rownum = 1
;
next_count := assign_count + 1;
--dbms_output.put_line(sql_stmt);
--execute immediate sql_stmt into jid;
insert into judge_project_list (project_id, judge_id, division, category) values (project.project_id, jid, project.division, project.category);
execute immediate 'update judge_assignment_count set assignment_count = ' || next_count || ' where judge_id = ' || jid;
end loop;
end loop;
commit;
结束;
问题
如何修改我的 SQL 声明,使每个项目有 4 名独特的评委,并且每个评委平均评判分配给他们的部门和类别的相同数量的项目?
要求
Population Project 需要Population Judge 审核(x) 次。 x = 4
- 每个项目都按部门和类别分组。
每位评委按部门和类别分组。
每个项目必须由 (x) 位独特的评委审核。
- 每位评委不得对同一个项目进行两次评审。
- 每位评委都应分配到与其所在部门和类别分组中的其他评委相同数量的项目进行评审。
样本源判断Table
create table judges(judge_id, division, category) as (
select 68, 'Elementary', 'ANY' from dual union all
select 19, 'Elementary', 'ANY' from dual union all
select 22, 'Elementary', 'ANY' from dual union all
select 32, 'Elementary', 'ANY' from dual union all
select 33, 'Elementary', 'ANY' from dual union all
select 37, 'Elementary', 'ANY' from dual union all
select 38, 'Elementary', 'ANY' from dual union all
select 40, 'Elementary', 'ANY' from dual union all
select 47, 'Elementary', 'ANY' from dual union all
select 62, 'Elementary', 'ANY' from dual union all
select 63, 'Elementary', 'ANY' from dual union all
select 13, 'Elementary', 'ANY' from dual union all
select 36, 'Elementary', 'ANY' from dual union all
select 55, 'Elementary', 'ANY' from dual union all
select 59, 'Elementary', 'ANY' from dual union all
select 60, 'Elementary', 'ANY' from dual union all
select 9, 'Junior', 'EC' from dual union all
select 10, 'Junior', 'EC' from dual union all
select 48, 'Junior', 'EC' from dual union all
select 11, 'Junior', 'LS' from dual union all
select 21, 'Junior', 'LS' from dual union all
select 23, 'Junior', 'LS' from dual union all
select 26, 'Junior', 'LS' from dual union all
select 31, 'Junior', 'LS' from dual union all
select 80, 'Junior', 'LS' from dual union all
select 14, 'Junior', 'PE' from dual union all
select 15, 'Junior', 'PE' from dual union all
select 24, 'Junior', 'PE' from dual union all
select 29, 'Junior', 'PE' from dual union all
select 30, 'Junior', 'PE' from dual union all
select 43, 'Junior', 'PE' from dual union all
select 53, 'Junior', 'PE' from dual union all
select 56, 'Junior', 'PE' from dual union all
select 57, 'Junior', 'PE' from dual union all
select 58, 'Junior', 'PE' from dual union all
select 65, 'Junior', 'PE' from dual union all
select 67, 'Junior', 'PE' from dual union all
select 69, 'Junior', 'PE' from dual union all
select 8, 'Senior', 'ANY' from dual union all
select 18, 'Senior', 'ANY' from dual union all
select 20, 'Senior', 'ANY' from dual union all
select 35, 'Senior', 'ANY' from dual union all
select 66, 'Senior', 'ANY' from dual union all
select 39, 'Senior', 'ANY' from dual union all
select 70, 'Senior', 'ANY' from dual union all
select 71, 'Senior', 'ANY' from dual union all
select 74, 'Senior', 'ANY' from dual union all
select 6, 'Senior', 'ANY' from dual union all
select 44, 'Senior', 'ANY' from dual union all
select 45, 'Senior', 'ANY' from dual union all
select 49, 'Senior', 'ANY' from dual union all
select 61, 'Senior', 'ANY' from dual union all
select 64, 'Senior', 'ANY' from dual union all
select 72, 'Senior', 'ANY' from dual union all
select 75, 'Senior', 'ANY' from dual union all
select 79, 'Senior', 'ANY' from dual union all
select 82, 'Senior', 'ANY' from dual
);
示例源项目Table
create table projects(project_id, division, category) as (
select 39, 'Elementary', 'ANY' from dual union all
select 40, 'Elementary', 'ANY' from dual union all
select 47, 'Elementary', 'ANY' from dual union all
select 48, 'Elementary', 'ANY' from dual union all
select 56, 'Elementary', 'ANY' from dual union all
select 57, 'Elementary', 'ANY' from dual union all
select 58, 'Elementary', 'ANY' from dual union all
select 60, 'Elementary', 'ANY' from dual union all
select 65, 'Elementary', 'ANY' from dual union all
select 66, 'Elementary', 'ANY' from dual union all
select 93, 'Elementary', 'ANY' from dual union all
select 94, 'Elementary', 'ANY' from dual union all
select 97, 'Elementary', 'ANY' from dual union all
select 104, 'Elementary', 'ANY' from dual union all
select 105, 'Elementary', 'ANY' from dual union all
select 107, 'Elementary', 'ANY' from dual union all
select 110, 'Elementary', 'ANY' from dual union all
select 112, 'Elementary', 'ANY' from dual union all
select 114, 'Elementary', 'ANY' from dual union all
select 117, 'Elementary', 'ANY' from dual union all
select 120, 'Elementary', 'ANY' from dual union all
select 121, 'Elementary', 'ANY' from dual union all
select 123, 'Elementary', 'ANY' from dual union all
select 124, 'Elementary', 'ANY' from dual union all
select 126, 'Elementary', 'ANY' from dual union all
select 127, 'Elementary', 'ANY' from dual union all
select 128, 'Elementary', 'ANY' from dual union all
select 133, 'Elementary', 'ANY' from dual union all
select 134, 'Elementary', 'ANY' from dual union all
select 136, 'Elementary', 'ANY' from dual union all
select 140, 'Elementary', 'ANY' from dual union all
select 142, 'Elementary', 'ANY' from dual union all
select 152, 'Elementary', 'ANY' from dual union all
select 153, 'Elementary', 'ANY' from dual union all
select 162, 'Elementary', 'ANY' from dual union all
select 167, 'Elementary', 'ANY' from dual union all
select 173, 'Elementary', 'ANY' from dual union all
select 174, 'Elementary', 'ANY' from dual union all
select 188, 'Elementary', 'ANY' from dual union all
select 27, 'Junior', 'EC' from dual union all
select 67, 'Junior', 'EC' from dual union all
select 82, 'Junior', 'EC' from dual union all
select 83, 'Junior', 'EC' from dual union all
select 99, 'Junior', 'EC' from dual union all
select 113, 'Junior', 'EC' from dual union all
select 115, 'Junior', 'EC' from dual union all
select 149, 'Junior', 'EC' from dual union all
select 164, 'Junior', 'EC' from dual union all
select 169, 'Junior', 'EC' from dual union all
select 185, 'Junior', 'EC' from dual union all
select 189, 'Junior', 'EC' from dual union all
select 18, 'Junior', 'LS' from dual union all
select 19, 'Junior', 'LS' from dual union all
select 20, 'Junior', 'LS' from dual union all
select 21, 'Junior', 'LS' from dual union all
select 23, 'Junior', 'LS' from dual union all
select 24, 'Junior', 'LS' from dual union all
select 26, 'Junior', 'LS' from dual union all
select 28, 'Junior', 'LS' from dual union all
select 29, 'Junior', 'LS' from dual union all
select 30, 'Junior', 'LS' from dual union all
select 78, 'Junior', 'LS' from dual union all
select 80, 'Junior', 'LS' from dual union all
select 90, 'Junior', 'LS' from dual union all
select 91, 'Junior', 'LS' from dual union all
select 106, 'Junior', 'LS' from dual union all
select 144, 'Junior', 'LS' from dual union all
select 150, 'Junior', 'LS' from dual union all
select 151, 'Junior', 'LS' from dual union all
select 156, 'Junior', 'LS' from dual union all
select 157, 'Junior', 'LS' from dual union all
select 159, 'Junior', 'LS' from dual union all
select 161, 'Junior', 'LS' from dual union all
select 165, 'Junior', 'LS' from dual union all
select 166, 'Junior', 'LS' from dual union all
select 168, 'Junior', 'LS' from dual union all
select 178, 'Junior', 'LS' from dual union all
select 180, 'Junior', 'LS' from dual union all
select 187, 'Junior', 'LS' from dual union all
select 22, 'Junior', 'PE' from dual union all
select 59, 'Junior', 'PE' from dual union all
select 61, 'Junior', 'PE' from dual union all
select 74, 'Junior', 'PE' from dual union all
select 81, 'Junior', 'PE' from dual union all
select 95, 'Junior', 'PE' from dual union all
select 96, 'Junior', 'PE' from dual union all
select 116, 'Junior', 'PE' from dual union all
select 145, 'Junior', 'PE' from dual union all
select 148, 'Junior', 'PE' from dual union all
select 158, 'Junior', 'PE' from dual union all
select 160, 'Junior', 'PE' from dual union all
select 172, 'Junior', 'PE' from dual union all
select 176, 'Junior', 'PE' from dual union all
select 181, 'Junior', 'PE' from dual union all
select 186, 'Junior', 'PE' from dual union all
select 14, 'Senior', 'ANY' from dual union all
select 15, 'Senior', 'ANY' from dual union all
select 42, 'Senior', 'ANY' from dual union all
select 43, 'Senior', 'ANY' from dual union all
select 44, 'Senior', 'ANY' from dual union all
select 45, 'Senior', 'ANY' from dual union all
select 46, 'Senior', 'ANY' from dual union all
select 49, 'Senior', 'ANY' from dual union all
select 51, 'Senior', 'ANY' from dual union all
select 52, 'Senior', 'ANY' from dual union all
select 53, 'Senior', 'ANY' from dual union all
select 54, 'Senior', 'ANY' from dual union all
select 75, 'Senior', 'ANY' from dual union all
select 76, 'Senior', 'ANY' from dual union all
select 77, 'Senior', 'ANY' from dual union all
select 92, 'Senior', 'ANY' from dual union all
select 108, 'Senior', 'ANY' from dual union all
select 118, 'Senior', 'ANY' from dual union all
select 119, 'Senior', 'ANY' from dual union all
select 125, 'Senior', 'ANY' from dual union all
select 131, 'Senior', 'ANY' from dual union all
select 132, 'Senior', 'ANY' from dual union all
select 135, 'Senior', 'ANY' from dual union all
select 137, 'Senior', 'ANY' from dual union all
select 138, 'Senior', 'ANY' from dual union all
select 139, 'Senior', 'ANY' from dual union all
select 141, 'Senior', 'ANY' from dual union all
select 143, 'Senior', 'ANY' from dual union all
select 146, 'Senior', 'ANY' from dual union all
select 154, 'Senior', 'ANY' from dual union all
select 171, 'Senior', 'ANY' from dual
);
甲骨文SQL代码
select
project_id
,division
,category
,judge_id
,best_match
from(
select
project.project_id
,project.division
,project.category
,judge.judge_id
,row_number() over(
partition by project.project_id
order by dbms_random.value
) as best_match
from frsf_fair.project_division_category project
left join (
select
judge_id
,division
,category
,row_number() over(
partition by division
order by dbms_random.value
) as r
from frsf_fair.judge_division_category
) judge on project.division = judge.division
and project.category = judge.category
) assignment
where best_match <= 4
数据输出示例
PROJECT_ID DIVISION CATEGORY JUDGE_ID BEST_MATCH
14 Senior ANY 72 1
14 Senior ANY 74 2
14 Senior ANY 20 3
14 Senior ANY 44 4
15 Senior ANY 79 1
15 Senior ANY 39 2
15 Senior ANY 75 3
15 Senior ANY 20 4
18 Junior LS 23 1
18 Junior LS 31 2
18 Junior LS 26 3
18 Junior LS 21 4
问题
count(*)/projects 的数量应该平均分配给裁判组的 Division 和 Category。相反,一些法官被分配到 20 个项目,而其他人被分配到很少的项目。我不知道如何修改我的查询,因此每个评委必须在项目部门和类别分组中引用相同次数。我要确保平等参与。
JUDGE_ID COUNT(*)
64 8
72 16
23 20
57 4
14 4
6 4
58 9
我能做的最好的就是这个查询:
with
t as (select judge_id jid, project_id pid, category cat, division div,
dense_rank() over (order by project_id) rp,
dense_rank() over (order by judge_id) rj,
count(1) over (partition by project_id) cnt
from judges join projects using (division, category)),
c(pid, jid, cat, div, rn, rp) as (
select pid, jid, cat, div, 1, rp from t where mod(rp, cnt) = mod(rj, cnt)
union all
select c.pid, t.jid, c.cat, c.div, rn + 1, c.rp
from c join t on c.rp = t.rp and c.jid <> t.jid
and mod(t.rp, t.cnt) = mod(t.rj + c.rn, t.cnt)
where rn < 3)
select * from c
它有什么作用?首先使用添加的行号和计数(rp、rj、cnt)进行基本连接。然后 mod()
使用这些列来连接锚查询 where mod(rp, cnt) = mod(rj, cnt)
中的行。然后是递归部分,只为每个项目添加所需数量的评委。也许有人不用递归就可以做到,但我做不到。您可以通过将随机 id
s 分配给判断并在查询中使用它们而不是真正的 id
s 来稍微随机化输出。将 3
替换为所需的评论数。
此 dbfiddle 显示 5 个项目、5 个评委、每个项目 3 个评论。评委不重复,均分。
编辑: 这是更正的基本查询:
with t as (
select category, division, project_id, judge_id,
dense_rank() over (partition by category, division
order by project_id) rp,
dense_rank() over (partition by category, division, project_id
order by judge_id) rj,
count(1) over (partition by project_id) cnt
from projects join judges using (category, division) )
select * from t
join (select level lvl from dual connect by level <= 3)
on mod(rj, cnt) = mod((rp -1) * 3 + lvl, cnt)
我检查了项目的结果(按 project_id 分组),每个项目都有 3 位不同的评委。 我检查了法官的结果(按类别、部门分组,judge_id),他的 class 中的每个法官都有相同数量的案件(如果没有足够的项目进行平均分配,则相差一个)。
逻辑与我的第一个查询相同。正如我所说,您可以先随机分配评委:
select row_number() over (order by dbms_random.value) rnd_jdg_id, judges.* from judges
并在主查询中使用这个假 ID 作为输入以获得完全随机分配。
我想到了一个利用我的 Oracle 数据库中的过程的解决方案。
我的方法是遍历每个项目 ID。 在我的循环中,它会将 1 循环到我需要的分配数量,在本例中为 4。
我们需要从法官列表中抽取一个随机法官 ID,方法是按升序计算他们已经分配了多少任务。我想先用最少的赋值。
他们的分配数如果增加+1
我们更新最终列表中的值table
我们循环直到给出项目分配的数量,然后评估下一个项目。
创建或替换过程 random_judge_project_list 为
assign_count number := 0; next_count number := 1; assignments number := 4; jid number; sql_stmt varchar2(4000); location varchar2(20);
开始
execute immediate 'truncate table judge_project_list'; execute immediate 'update judge_assignment_count set assignment_count = 0'; /*We First Need to Loop through Each Project*/ for project in ( select project_id ,division ,category as source_category ,case division when 'Junior' then category else 'ANY' end as category from projects a order by division asc, category asc ) loop /*While Looping we then need to assign judges randomly*/ for assign in 1 .. assignments loop select judge_id into jid from( select * from judge_assignment_count where division = project.division and judge_id not in (select judge_id from judge_project_list where project_id = project.project_id) order by assignment_count asc, dbms_random.random asc ) where rownum = 1 ; select assignment_count into assign_count from judge_assignment_count where judge_id = jid and rownum = 1 ; next_count := assign_count + 1; --dbms_output.put_line(sql_stmt); --execute immediate sql_stmt into jid; insert into judge_project_list (project_id, judge_id, division, category) values (project.project_id, jid, project.division, project.category); execute immediate 'update judge_assignment_count set assignment_count = ' || next_count || ' where judge_id = ' || jid; end loop; end loop; commit;
结束;