从相同列等于两个不同的事物的表中选择?

时间:2012-06-19 17:35:17

标签: php mysql

我有一个有16个表的数据库,但只有四个与此相关。数据库跟踪不同的服务器,服务器信息(CPU,RAM,IP地址等)及其运行的软件。软件和机器通过连接表相关联。

CREATE TABLE machsoftjt (
     mid int(4) NOT NULL,
     sid int(4) NOT NULL,
     slid int(4) NOT NULL,
     notes varchar(255) default NULL,
     UNIQUE KEY mid (mid,slid)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
mid是机器表中机器的id,sid是软件表中软件的id,包含软件名称和软件版本,slid是软件列表中的软件列表id(只列出正在运行的软件的表)并用于唯一约束,以便在执行软件升级时,我没有运行同一软件的两个不同版本的一台机器的条目。因此,如果我有运行Microsoft Word 2010(sid为1,滑动为1)和Adobe Photoshop 5(sid为2且滑动为2)的machine1(中间为1),则该表将具有< / p>
mid  sid   slid
1    1     1
1    2     2

我想从此表中选择同时运行Microsoft Word和Adobe Photoshop的所有计算机。

SELECT machines.machinename FROM (machines INNER JOIN machsoftjt ON 
  machines.mid=machsoftjt.mid) INNER JOIN software ON machsoftjt.sid=software.sid
  WHERE machsoftjt.slid='1' AND machsoftjt.slid='2'

当我运行此查询时,我没有得到任何回复当我运行此查询时,我没有得到任何回报。我现在很难过,也无法想出任何其他的东西。非常感谢所有帮助。

3 个答案:

答案 0 :(得分:3)

这需要自我加入。大致是:

SELECT machines.machinename 
FROM machines 
INNER JOIN machsoftjt AS m1 ON machines.mid=m1.mid 
INNER JOIN machsoftjt AS m2 ON machines.mid=m2.mid 
WHERE m1.slid='1' AND m2.slid='2'

获取软件名称,大致:

SELECT machines.machinename, s1.*, s2.*
FROM machines 
INNER JOIN machsoftjt AS m1 ON machines.mid=m1.mid 
INNER JOIN machsoftjt AS m2 ON machines.mid=m2.mid 
INNER JOIN software s1 ON m1.sid=s1.sid
INNER JOIN software s2 ON m2.sid=s2.sid
WHERE m1.slid='1' AND m2.slid='2'

您可能必须为s1和s2

中的相关列添加别名

答案 1 :(得分:2)

因为这条线而失败了:

WHERE machsoftjt.slid =&#39; 1&#39; AND machsoftjt.slid =&#39; 2&#39;

machsoftjt不能等于1和2;所以你没有得到任何结果。

您必须分别查询每个包。

我认为像这样的事情应该这样做:

SELECT machines.machinename 
FROM machines 
WHERE mid IN (SELECT mid FROM machsoftht WHERE sid=1) AND 
 mid IN (SELECT mid FROM machsoftht WHERE sid=2)

答案 2 :(得分:2)

不需要自联接或子查询:

只需加入machsoftjt一次,然后让机器满足所有条件,就可以将HAVING子句与GROUP BY结合使用,只检索机器其中两行已加入,其中软件 Photoshop或Word

SELECT
    a.machinename
FROM
    machines a
INNER JOIN
    machsoftjt b ON a.mid = b.mid
    AND b.slid IN (1,2)
GROUP BY
    a.mid
HAVING
    COUNT(*) = 2

此外,由于slid的类型为INT,因此12周围不需要引号。

这种方法也很灵活,因为它很容易添加/删除条件。如果您想要所有slid s(1,2,4,8)的机器,只需调整IN子句并调整COUNT(*)子句中的HAVING即可4(因为列表中有4个值,机器必须满足)。