0

我有一个包含 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是softlist表中的软件列表ID(仅列出正在运行和使用的软件的表用于唯一约束,以便在执行软件升级时,我没有一台机器运行同一软件的两个不同版本的条目)。因此,如果我有 machine1(中间值为 1)运行 Microsoft Word 2010(sid 为 1,slid 为 1)和 Adob​​e Photoshop 5(sid 为 2,slid 为 2),表格将

mid  sid   slid
1    1     1
1    2     2

我想从这个表中选择所有运行 Microsoft Word 和 Adob​​e 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'

当我运行这个查询时,我没有得到任何回报当我运行这个查询时,我没有得到任何回报。我现在很困惑,想不出别的办法。所有帮助将不胜感激。

4

3 回答 3

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 中的相关列起别名

于 2012-06-19T17:45:12.020 回答
2

由于这条线,它失败了:

其中 machsoftjt.slid='1' 和 machsoftjt.slid='2'

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)
于 2012-06-19T17:42:03.573 回答
2

不需要自联接或子查询:

只需加入machsoftjt一次,然后要获得满足所有条件的机器,您可以将HAVING子句与 a 结合使用,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

此外,由于slidis 的类型INT,您不需要在 and 周围1加上引号2

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

于 2012-06-19T18:10:26.753 回答