2011-05-20 179 views
1

我有四个值表:教师,认证,block_subjects和块以及两个关系表:instructor_certifications和subject_certification。就像这样:加入两个多对多关系,'all'operator

block -- block_subject 
      | 
      | 
subject_certification 
      | 
      | 
    certification 
      | 
      | 
instructor_certification 
      | 
      | 
     instructor 

我想要一个查询,会告诉我,每个块,其中教官师资块。具体来说,我不想指定块ID作为查询的一部分;我想根据不同的标准选择多个块。

这里是(非工作)查询我目前有:

select inst.name, inst.id 
from instructor as inst 
join instructor_certification as ic on inst.id = ic.instructor_fid and 
ic.certification_fid = all (
    select cert.id 
    from block_subject as bs 
    join subject_certification as bsc on bsc.block_fid = bs.id 
    join certification as cert on bsc.certification_fid = cert.id 
    where bs.id = any (
     select bs.id 
    from block as b 
     join block_subject as bs on b.subject_fid = bs.id 
     where (b.start_date, b.end_date) overlaps (?, ?) 
    ) 
) 

显然,这并不工作,因为“所有”收集所有在日期范围内的所有block_subject所需的认证。

编辑:另外我应该澄清,实际上,每个block_subject需要多个认证。

+0

听起来像你对我要求的关系运算符是[师](http://www.simple-talk.com/sql/t-sql-编程/划分我们的关系SQL的分支/):“提供所有部分的供应商” - >“可以教授块上所有主题的教师”,或许? – onedaywhen 2011-05-20 06:09:04

+0

这看起来像我需要的......哦,从来没有真正采取数据库类的乐趣。 – gibbss 2011-05-20 06:51:47

+0

好的,我将其更改为新的要求。 – Hogan 2011-05-20 10:15:09

回答

1

编辑后:

如果要求每块每名教师多证书:

select b.id as blockid, bs.subject_id as subject_id, i.id as inscructorid, count(ic.certification_id) as numCerts 
from block b 
join block_subject bs on b.id = bs.block_id 
join subject_certification sc on bs.subject_id = sc.subject_id 
join instructor_certification ic on sc.certification_id = ic.certification_id 
join instructor i on ic.instructor_id = i.id 
group by b.id, bs.subject_id, i.id 
having count(ic.certification_id) > 1 

您的问题,指出 “每块”。所以,从块开始,然后做连接。像这样:

select * 
from block b 
join block_subject bs on b.id = bs.block_id 
join subject_certification sc on bs.subject_id = sc.subject_id 
join instructor_certification ic on sc.certification_id = ic.certification_id 
join instructor i on ic.instructor_id = i.id 

您现在可以添加任何您想要的标准。

特定块?

日期范围?

where @Date between b.start_date and b.end_date 

指导员?

where i.id = @inid 

认证?或者其组合。

0

给这个镜头。

declare @Date datetime 

set @Date = '01/01/2011' 

select inst.name, inst.id 
from instructor as inst 
join instructor_certification as ic on inst.id = ic.instructor_fid 
and ic.certification_fid in (
    select cert.id 
    from block_subject as bs 
    join subject_certification as bsc on bsc.block_fid = bs.id 
    join certification as cert on bsc.certification_fid = cert.id 
    where bs.id in (select bs.id 
     from block as b 
     join block_subject as bs on b.subject_fid = bs.id 
     where @Date between b.start_date and b.end_date)) 
    ) x 
0

只是教官......

select 
    i.* 
from 
    instructor i on 
where 
    exists (
    select * 
    from 
     block b 
     join block_subject bs on b.id = bs.block_id 
     join subject_certification sc on bs.subject_id = sc.subject_id 
     join instructor_certification ic on sc.certification_id = ic.certification_id 
     WHERE 
     ic.instructor_id = i.id 
     AND 
     ..other filters here 
     )