我想将一个表中的行分配给另一表中的行,而在SQL oracle中,该表可以相等地占用行

时间:2019-02-26 07:30:10

标签: sql oracle plsql

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

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

学生:(亚当,班纳特,埃尔默,贾斯汀,路易,诺亚,杰克)

老师:(李奥,凯尔,伊桑)

注意:

  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

我该怎么做?

2 个答案:

答案 0 :(得分:6)

这不一定会按照您希望的顺序分配教师,但是仍会按照您希望的比例分配。它使用<!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body> <div class="social"> <a href="#" class="fa fa-facebook"></a> <a href="#" class="fa fa-twitter"></a> </div> </body> </html> 函数将名称放入存储桶中,并为每行分配适当的存储桶编号。

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

NTILE

Demo

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;

答案 1 :(得分:2)

一种方法:给学生和老师编号。然后使用除数为教师数的模来加入:

select
  s.name as student,
  t.name as teacher
from (select name, row_number() over(order by name) as rn from teachers) t
join (select name, row_number() over(order by name) as rn from students) s
  on mod(s.rn - 1, (select count(*) from teachers)) = t.rn -1
order by teacher, student;