2015-04-07 52 views
0
CREATE TABLE User(uid INTEGER AUTO_INCREMENT,address VARCHAR(40),city 
VARCHAR(20),state VARCHAR(20), 

我试过到目前为止:查询连接3台

SELECT User.uid, Job.jobid, Protein.pid FROM User 
JOIN Job ON (Job.uid = User.uid) 
JOIN Protein ON (Job.pid = Protein.pid) 

我无法弄清楚如何找到利用所有蛋白质的工作。

+0

如何是与蛋白质相关的工作。由于作业与具有多对多关系的蛋白质相关,您可能需要创建一个名为job_protein的连接表来标识特定作业参考的蛋白质。 –

+0

所有蛋白质都与您的“蛋白质”表 –

+0

没有关系,您是指蛋白质表中的每一个条目? –

回答

0

该查询会给你已在蛋白质表中每个蛋白的一个每一项工作的job_ids,只有在蛋白质表中每个蛋白的一个

select j.job_id 
    from job j 
    inner join job_proteins p 
     on j.job_id = p.jid 
    group by j.job_id 
    having group_concat(p.pid order by p.pid asc) = 
     (select group_concat(pid order by pid asc) from protein); 

演示:http://sqlfiddle.com/#!9/febf6/5

它有必要添加一张额外的表格以表示作业和蛋白质之间的关系,这是您原始模式定义中缺少的关系

如果某个作业确实无法使用多于一个相同的蛋白质,那么t母鸡下面的查询也足够了:

select j.job_id, count(j.job_id) 
    from job j 
    inner join job_proteins p 
     on j.job_id = p.jid 
    group by j.job_id 
    having count(j.job_id) = (select count(pid) from protein); 

更新演示:http://sqlfiddle.com/#!9/febf6/9

注意更新的演示将返回相同的蛋白质样品的工作列出了两次 - 因此,一个作业无法使用超过需求一个相同的蛋白质。

如果作业可以使用相同的蛋白质不止一次,不过没关系,你想将其包括在使用所有的蛋白质至少一次作业的结果,这个查询就足够了:

select j.job_id, count(j.job_id) 
    from job j 
    inner join job_proteins p 
     on j.job_id = p.jid 
    group by j.job_id 
    having count(distinct p.pid) = (select count(pid) from protein); 
+0

什么是group_concat? –

+0

这是一个将一组结果连接成一个字符串的mysql函数。 https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat。例如在子查询中,而不是为每个pid返回一行,它只返回一个类似于“1,2,3,... N”的字符串,其中N是表中的最后一个pid –

+0

所以这个查询会获得利用每一种蛋白质的工作? –