我如何修改我的SQL语句,使每个项目都有(x)个评委,并且每个评委都在他们的群体中平均参与? 问题:
如何修改我的SQL语句,使每个项目都有4个唯一的评判员,每个评判员为其指定的部门和类别平均评判相同数量的项目 要求 人口项目需要人口法官(x)次审查。 x=4我如何修改我的SQL语句,使每个项目都有(x)个评委,并且每个评委都在他们的群体中平均参与? 问题:,sql,oracle,distribution,population,Sql,Oracle,Distribution,Population,如何修改我的SQL语句,使每个项目都有4个唯一的评判员,每个评判员为其指定的部门和类别平均评判相同数量的项目 要求 人口项目需要人口法官(x)次审查。 x=4 每个项目按部门和类别分组 每一位法官都按部门和类别分组 每个项目都必须由(x)名唯一的评审员进行评审 每位评委不得对同一项目进行两次评审 每名法官应被分配与其他法官在其司和职类分组中同等数量的项目进行审查 样本源判断表 示例源项目表 Oracle SQL代码 问题 计数(*)/项目的数量应平均分配给各部门和类别的评委。相反,一些评委被
- 每个项目按部门和类别分组
- 每一位法官都按部门和类别分组
- 每个项目都必须由(x)名唯一的评审员进行评审
- 每位评委不得对同一项目进行两次评审
- 每名法官应被分配与其他法官在其司和职类分组中同等数量的项目进行审查
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
我检查了项目的结果(按项目id分组),每个项目有3个不同的评判。
我检查了法官的结果(按类别、分区、法官id分组),他们班上的每个法官都有相同数量的案件(如果没有足够的项目进行平等分配,则会相差一个)
逻辑与我的第一个查询中的相同。正如我所说的,你可以先将评委随机分组:
select row_number() over (order by dbms_random.value) rnd_jdg_id, judges.* from judges
并在主查询中使用这个假id作为输入,以获得完全随机的赋值。我利用Oracle数据库中的过程提出了一个解决方案 我的方法是循环遍历每个项目id。 在我的循环中,它将循环1到我所需的分配数量,在本例中为4
assign_count number := 0;
next_count number := 1;
assignments number := 4;
jid number;
sql_stmt varchar2(4000);
location varchar2(20);
开始
结束我尝试了一下代码,但它不能很好地扩展到整个数据集。我继续,在我的原始帖子中包含了两个表的整个create表。(它们很小)。我可以看到您的代码的发展方向,我尝试了一些变化,但仍然得到相同的结果。评委人数分布不均匀,或者每个项目ID的评委人数差异很大。我会继续修改您提供的代码,我想我可能能够让它以我需要的方式连接起来。当我们有57位评委和126个项目时,我会看得更清楚;-)我认为这样做是可行的,锚查询每次都需要从3开始(不像现在这样),只得到1个判断(不是很多),然后递归地加入2个。如果我有更多的空闲时间,我会尽力去做。如果你能做到(以任何方式)请通知我,我很好奇:)
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
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)
select row_number() over (order by dbms_random.value) rnd_jdg_id, judges.* from judges
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;