了解有工作或正在上课的囚犯

时间:2014-05-14 22:12:18

标签: mysql

表格如下:

Person
person_ssn
first_name
middle_name
last_name


Prisoner
prisoner_id
person_ssn

Work
prisoner_id
job_id

Class
prisoner_id
class_id

我有兴趣获得有工作或班级的囚犯的数量。任何提示都表示赞赏。

到目前为止我有什么

select count(prisoner.prisoner_id)
FROM prisoner
INNER JOIN work on prisoner.prisoner_id = work.prisoner_id
INNER JOIN school on prisoner.prisoner_id = school.prisoner_id;

这似乎正在恢复那些既有工作又在学校的囚犯的数量。

3 个答案:

答案 0 :(得分:1)

您在第一个内部联接结果上使用了第二个内部联接 - 这意味着您检查囚犯和工作囚犯的交叉点,然后检查工作囚犯与上课的人员的交集

试试这个:

select count(*) from (
   (select * from 
      prisoner inner join work on prisoner.prisoner_id = work.prisoner_id) as first
   union
   (select * from
      prisoner inner join class on prisoner.prisoner_id = class.prisoner_id) as second);

答案 1 :(得分:1)

使用 left 连接,但要求至少有一个连接成功,方法是检查连接表中的列是否为空(错过的左连接在连接表的列中具有所有空值):

select count(distinct prisoner.prisoner_id)
from prisoner
left join work on prisoner.prisoner_id = work.prisoner_id
left join school on prisoner.prisoner_id = school.prisoner_id
where work.prisoner_id is not null
or school.prisoner_id is not null

请注意,我在计数中添加了distinct,以防囚犯有多个工作或多次上课,否则会多次计算囚犯。

答案 2 :(得分:0)

我认为处理此查询的最有效方法是使用exists

select count(*)
from prisoners p
where exists (select 1 from work w where w.prisoner_id = p.prisoner_id) or
      exists (select 1 from class c where c.prisoner_id = p.prisoner_id);

这适用于work(prisoner_id)class(prisoner_id)上的索引。