admin

我想将一个表中的行分配给另一表中的行,这在SQL oracle中可以采用相等数量的行

sql

我正在尝试编写一个SQL查询,该查询会将记录从一个表分发到另一个表,该表的数目相同。

在此示例中,我有两个表StudentsTeachers,我想将学生分配给每个老师。

学生:(Adam,Bennet,Elmer,Justin,Louis,Noah,Jack)

老师:(Leo,Kyle,Ethan)

注意:

  1. 一个学生最多只能有一位老师
  2. 每位老师的学生人数应与其他老师的人数相同…
  3. …除非学生人数不是教师人数的确切倍数,否则在这种情况下,必须尽可能平均地在教师之间平均分配学生

例如,如果我们有七个学生和三个老师,则前两个老师将带两个学生,最后一个将带三个学生。

结果:

Student | Teacher
--------+--------
Adam    | Leo
Bennet  | Leo
Elmer   | Kyle
Justin  | Kyle
Louis   | Ethan
Noah    | Ethan
Jack    | Ethan

如何在Oracle SQL中做到这一点?

也:如果我要增加课程,并且学生必须在不同的强迫下有不同的老师…结果:

Student | Teacher | coerces 
--------+---------+---------
Adam    | Leo     |  1
Bennet  | Leo     |  1
Elmer   | Kyle    |  1
Justin  | Kyle    |  1
Louis   | Ethan   |  1
Noah    | Ethan   |  1
Jack    | Ethan   |  1
Louis   | Leo     |  2
Noah    | Leo     |  2
Jack    | Kyle    |  2
Adam    | Kyle    |  2
Bennet  | Ethan   |  2
Elmer   | Ethan   |  2
Justin  | Ethan   |  2

我该怎么办?


阅读 186

收藏
2021-06-07

共1个答案

admin

这不一定会按照您希望的顺序分配教师,但是仍然会按照您希望的比例分配。它使用该NTILE函数将名称放入存储桶中,并为每行分配适当的存储桶编号。

如果您想下订单,则必须为教师和学生提供一个唯一的ID列。

with tch as
(
 select t.*, row_number() OVER ( ORDER BY name ) as n from teachers t
 ),
ct AS
 ( 
  select count(*) as cnt from Teachers
  )
 select s.name as student,tch.name as teacher from
 (

     SELECT name, NTILE(cnt) OVER (partition by cnt ORDER BY name)  AS n 
         FROM Students cross join
       ct
) s join tch on tch.n = s.n;

演示版

 Student| Teacher 
 -----  | ----
 Adam   | Ethan
 Bennet | Ethan
 Elmer  | Ethan
 Jack   | Kyle 
 Justin | Kyle 
 Louis  | Leo  
 Noah   | Leo
2021-06-07