表格如下:
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;
这似乎正在恢复那些既有工作又在学校的囚犯的数量。
答案 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)
上的索引。