查询语句:类似于“没有”的SQL查询?

7

我正在尝试编写一个查询,以返回缺少某个软件的主机:

Host                    Software
A                       Title1
A                       Title2
A                       Title3 
B                       Title1
B                       Title3
C                       Title4
C                       Title3

如何查询缺少Title2(应该是B和C)的主机?我尝试使用GROUP BY、HAVING以及使用COUNT的子查询,但似乎没有正确的思路。

请发布示例数据和您迄今为止所做的查询。 - YvesR
2个回答

19

我认为一个更简单的方法是:

select software
from HostSoftware hs
group by software
having max(case when software = 'Title2' then 1 else 0 end) = 0

这不需要相关的子查询,并且在大多数数据库中,它应该会产生更好的执行计划。


什么是 title - brandones
@brandones . . . 很好的发现。那应该是“软件”。 - Gordon Linoff
更好的执行效率是因为子查询不需要重新扫描整个表格吗?虽然WHERE在GROUP BY之前执行,但最好还是避免使用那个子查询,对吧? - KLDavenport
2
@KLDavenport...实际上,更好的执行是因为它不需要额外的步骤来删除重复项。 接受的解决方案将返回重复行。 - Gordon Linoff
@GordonLinoff - 可能有错误,但如果你想找到没有特定软件的主机,那么应该是 select host ... group by host ... 吧? - Sam
@Sam...干得好。 - Gordon Linoff

13
SELECT Host FROM HostSoftware
WHERE NOT EXISTS (
    SELECT * FROM HostSoftware AS InnerSoftware
    WHERE InnerSoftware.Host = HostSoftware.Host AND InnerSoftware.Software ='Title2'
)

谢谢您的编辑!我不知道如何在 SO 的移动版本上进行代码格式化 :-/ - Ian Newson
括号内的位检索具有特定软件的主机的行。如果返回任何行,则 EXISTS 谓词得到满足,否定它表示如果该主机没有具有特定软件的内部行存在,则返回外部行。 - Ian Newson
我理解exists谓词和否定,但令我困惑的是子查询SELECT * FROM HostSoftware AS InnerSoftware WHERE InnerSoftware.Host = HostSoftware.Host AND InnerSoftware.Software ='Title2'返回与SELECT * FROM HostSoftware where Software='Title2'相同的记录集,但将其用作子查询会使MySQL感到不快。 - Cthulhucalling
我的意思是“空记录集”。 - Cthulhucalling
InnerSoftware.Host = HostSoftware.Host 的作用类似于连接的 ON 子句。它将外部查询与内部查询关联起来。 - Ian Newson
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接