了解教授中至少有一名SQL博士生的百分比

了解教授中至少有一名SQL博士生的百分比,sql,Sql,比如说在大学里,有硕士生、博士生和教授。每个学生只能有一位教授作为他的导师 我们怎样才能知道教授中至少有一名博士生的比例是多少 我在想这样的事情: select id as p.profID from professors p where EXISTS (select * from students s where s.advisorID = p.profID and s.enrollmentLevel = "PhD"); select 100.0 *

比如说在大学里,有硕士生、博士生和教授。每个学生只能有一位教授作为他的导师

我们怎样才能知道教授中至少有一名博士生的比例是多少

我在想这样的事情:

select id as p.profID from professors p 
  where EXISTS (select * from students s 
                where s.advisorID = p.profID and s.enrollmentLevel = "PhD");
select 100.0 * count(*) from (select id as p.profID from professors p 
  where EXISTS (select * from students s 
                where s.advisorID = p.profID and s.enrollmentLevel = "PhD"))
  / (select count(*) from professors);
使用上述查询,将其稍微更改为:

select id as p.profID from professors p 
  where EXISTS (select * from students s 
                where s.advisorID = p.profID and s.enrollmentLevel = "PhD");
select 100.0 * count(*) from (select id as p.profID from professors p 
  where EXISTS (select * from students s 
                where s.advisorID = p.profID and s.enrollmentLevel = "PhD"))
  / (select count(*) from professors);
我不是每天都使用SQL,所以它的语法

select count(*) from (select * from students limit 10);

无效,并且不会返回10,因此上面的第二个查询无效。怎么写呢?

解决这个问题有很多方法

如果有些教授没有学生,我会选择:

select avg( has_student_phd::int ) as phd_ratio
from (select p.*,
             (exists (select 1 from students s where s.advisorId = p.profId and s.enrollmentLevel = 'PhD')
             ) as has_student_phd
      from professors p
     ) p;
这使用Postgres语法

但是,如果您只关心至少有一名学生的教授,那么:

select ( count(distinct s.advisorId) filter (where s.enrollmentLevel = 'PhD') * 1.0 /
         count(distinct s.advisorId)
       ) 
from students s;
注意:它们都使用Postgres语法,但是可以很容易地适应MySQL

或者,两个子查询的比率:

select (select count(distinct s.advisorId) from students s where s.enrollmentLevel = 'PhD') * 1.0 /
       (select count(*) from professors p)

有很多方法可以解决这个问题

如果有些教授没有学生,我会选择:

select avg( has_student_phd::int ) as phd_ratio
from (select p.*,
             (exists (select 1 from students s where s.advisorId = p.profId and s.enrollmentLevel = 'PhD')
             ) as has_student_phd
      from professors p
     ) p;
这使用Postgres语法

但是,如果您只关心至少有一名学生的教授,那么:

select ( count(distinct s.advisorId) filter (where s.enrollmentLevel = 'PhD') * 1.0 /
         count(distinct s.advisorId)
       ) 
from students s;
注意:它们都使用Postgres语法,但是可以很容易地适应MySQL

或者,两个子查询的比率:

select (select count(distinct s.advisorId) from students s where s.enrollmentLevel = 'PhD') * 1.0 /
       (select count(*) from professors p)

您可以将EXISTS的结果作为整数1或0用于平均值内的TRUE或FALSE:


删除Mysql对int:::int的显式强制转换。

您可以使用EXISTS的结果作为整数1或0表示AVG中的TRUE或FALSE:


删除Mysql的显式转换为int:::int。

我删除了不一致的数据库标记。请仅使用您真正使用的数据库进行标记。我删除了不一致的数据库标记。请仅标记您真正使用的数据库。哦,您的解决方案2和3 profID真的是advisorID吗?这是非常有趣的第三个解决方案。。。似乎如果有N个学生和M个教授,我在这个问题上的初始解决方案将花费*M个时间。。。但是你的第三个解决方案需要时间。我尝试了类似于SelectCountDistinct advisorID from students的方法,其中enrollmentLevel='PhD'*1.0/SelectCountDistinct advisorID from students;我可以简单地使用学生表,因为在我的用例中,我甚至不知道在哪里可以找到教授表。。。可能是在员工桌上或者类似的地方that@nonopolarity . . . 如果性能是一个问题,那么第一个方法将使用Op*logs time,因为我将假设适当的索引。其他两种方法效率较低。@非极性。至于你的第一个问题,我几乎总是在主键之后命名外键。我只是糊涂了。我更新了答案。哦,你的解决方案2和3真的是advisorID吗?这是非常有趣的第三个解决方案。。。似乎如果有N个学生和M个教授,我在这个问题上的初始解决方案将花费*M个时间。。。但是你的第三个解决方案需要时间。我尝试了类似于SelectCountDistinct advisorID from students的方法,其中enrollmentLevel='PhD'*1.0/SelectCountDistinct advisorID from students;我可以简单地使用学生表,因为在我的用例中,我甚至不知道在哪里可以找到教授表。。。可能是在员工桌上或者类似的地方that@nonopolarity . . . 如果性能是一个问题,那么第一个方法将使用Op*logs time,因为我将假设适当的索引。其他两种方法效率较低。@非极性。至于你的第一个问题,我几乎总是在主键之后命名外键。我只是糊涂了。我更新了答案。