使用 EXISTS 引入子查询

Introduce sub query with EXISTS

我有一个很长的查询,在我执行时抛出异常。 查询:

SELECT HostID,HostName,RackID,HostTypeID,DomainName,RackNumberOfHeightUnits,RackStartHeightUnits 
FROM tHosts, tDomains   
WHERE tHosts.DomainID=tDomains.DomainID AND (RackID IN ( SELECT tRacks.Name,tRacks.RackID,tRacks.SiteID,tRacks.Description,NumberOfHeightUnits   
                                                         FROM tDomains, tSites, tRacks   
                                                         WHERE   tDomains.AccountID= tSites.AccountID    
                                                         AND tSites.SiteID = tRacks.SiteID    
                                                         AND tSites.SiteID = 2  
                                                         AND tDomains.AccountID=1 ) 
AND  SiteID IN (SELECT SiteID FROM tSites WHERE SiteID IN (SELECT SiteID FROM tSites WHERE AccountID=1)))AND AccountID=1

正在为这里的查询完成:

SELECT tRacks.Name,tRacks.RackID,tRacks.SiteID,tRacks.Description,NumberOfHeightUnits 
                                                         FROM tDomains, tSites, tRacks  
                                                         WHERE tDomains.AccountID= tSites.AccountID  
                                                         AND tSites.SiteID = tRacks.SiteID  
                                                         AND tSites.SiteID = 2  
                                                         AND tDomains.AccountID=1 

**错误:**当子查询没有引入EXISTS时,select列表中只能指定一个表达式。
提前致谢。

IN 你必须 return 一列,你要比较的列:

改变这个

 ...AND (RackID IN ( SELECT tRacks.Name,tRacks.RackID,tRacks.SiteID,tRacks.Description,NumberOfHeightUnits   
                     FROM tDomains, tSites, tRacks ...

为此:

... AND (RackID IN ( SELECT tRacks.RackID FROM tDomains, tSites, tRacks ...

在这个地方不会使用其他列"outside"

但是 - 老实说 - 整个查询看起来 - 嗯 - 可以改进......

后续子查询

SELECT SiteID FROM tSites WHERE SiteID IN (SELECT SiteID FROM tSites WHERE AccountID=1)

似乎等于

SELECT SiteID FROM tSites WHERE AccountID = 1

您可以将第一个替换为第二个,希望能消除错误

我认为您应该重新审视您的 SQL 并准确确定您认为需要以现有方式编写查询的原因,这不仅是为了您在调试时保持理智,还因为它如果对正在发生的事情有更多的了解,您似乎可以大大简化此查询。

从您的 SQL 来看,您似乎想要给定帐户(ID 1)和站点(ID 2)的所有主机、域和机架详细信息

当您在 select 中使用逗号分隔的 table 列表编写查询时,它 a) 立即更难阅读并且 b) 以后其他开发人员更有可能谁必须来修改您的查询,您的第一个 select 将被重写为:

SELECT (columns)
FROM tHosts
INNER JOIN tDomains ON tDomains.DomainID = tHosts.DomainID

然后您想要加入以查找 ID 为 2 的站点和 ID 为 1 的帐户的机架详细信息。您的 tDomains 和 tSites 具有共同的 AccountID 列,因此您可以加入这些:

INNER JOIN tSites ON tSites.AccountID = tDomains.AccountID

并且您的 tRacks 和 tSites 有一个共同的 SiteID 列,因此您可以加入:

INNER JOIN tRacks ON tRacks.SiteID = tSites.SiteID

然后您可以应用您的 where 子句将结果过滤到您需要的标准:

WHERE tDomains.AccountID = 1
AND tSites.SiteID = 2

您现在有以下查询:

SELECT HostID
     , HostName
     , RackID
     , HostTypeID
     , DomainName
     , RackNumberOfHeightUnits
     , RackStartHeightUnits 
FROM tHosts
INNER JOIN tDomains ON tDomains.DomainID = tHosts.DomainID
INNER JOIN tSites ON tSites.AccountID = tDomains.AccountID
INNER JOIN tRacks ON tRacks.SiteID = tSites.SiteID
WHERE tDomains.AccountID = 1
AND tSites.SiteID = 2

您 SQL 中的最后一行似乎没有必要,因为您正在 select 再次为 ID 为 1 的帐户输入站点 ID(并且您已经在您的内部 select).

这里可能缺少一些东西,因为如果不看 table 定义就很难理解您的确切域,但您似乎可以提高可读性,但更重要的是提高查询性能变化不大?