简体   繁体   English

使用EXISTS引入子查询

[英]Introduce sub query with EXISTS

I Have a long query which is throwing an exception when i execute. 我有一个很长的查询,当我执行时抛出异常。 Query: 查询:

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

It is accomplishing for the query in here: 它在这里完成查询:

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 

**The error: ** Only one expression can be specified in the select list when the subquery is not introduced with EXISTS. **错误:**当EXISTS未引入子查询时,只能在选择列表中指定一个表达式。
Thanx in advance. Thanx提前。

With IN You must return one column, the column you want to compare against: 使用IN您必须返回一列,即要与之比较的列:

Change this 改变这个

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

To this: 对此:

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

In this place no other column will be used "outside" 在这个地方没有其他专栏将被用于“外面”

But - to be honest - the whole query looks like - uhm - improveable ... 但是 - 说实话 - 整个查询看起来像 - 嗯 - 可改进......

Following sub-query 以下子查询

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

seems to be equal to 似乎等于

SELECT SiteID FROM tSites WHERE AccountID = 1

You can replace first one with second hoping to get rid of the error 您可以用第二个替换第一个希望摆脱错误

I think you should re-look at your SQL and determine exactly why you think you need to write the query in the way you have, not only for your own sanity when debugging it, but because it seems that you could simplify this query a great deal if there was a little more understanding of what was going on. 我认为你应该重新查看你的SQL,并确定你认为你需要以你的方式编写查询的确切原因,不仅仅是为了你在调试它时的理智,而且因为你似乎可以简化这个查询。如果对正在发生的事情有更多了解,请进行交易。

From your SQL it seems like you want all host, domain and rack details for a given account (with ID 1) and site (with ID 2) 从您的SQL看起来您想要给定帐户(ID为1)和站点(ID为2)的所有主机,域和机架详细信息

When you write your query with a comma seperated list of tables in your select, it's a) straight away more diffcult to read and b) more likely to another developer later down the line who has to come and amend your query, your first select would be re-written as: 当您在选择中使用逗号分隔的表格列表编写查询时,a)a)更难以阅读,b)更有可能是另一位开发人员后来必须来修改您的查询,您的第一个选择将被重写为:

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

You then want to join to find the rack details for the site with ID 2 and account with ID 1. Your tDomains and tSites have common AccountID columns, so you can join on those: 然后,您想要加入以查找ID为2的帐户和ID为1的帐户的机架详细信息。您的tDomains和tSites具有常见的AccountID列,因此您可以加入以下内容:

INNER JOIN tSites ON tSites.AccountID = tDomains.AccountID

and your tRacks and tSites have a common SiteID column so you can join on those: 并且您的tRack和tSites有一个共同的SiteID列,因此您可以加入以下内容:

INNER JOIN tRacks ON tRacks.SiteID = tSites.SiteID

you can then apply your where clause to filter the results down to your required criteria: 然后,您可以应用where子句将结果过滤到所需的条件:

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

You now have the following query: 您现在有以下查询:

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

The final line in your SQL seems unnecessary, as you are selecting the site ids for the account with ID 1 again (and you've already filtered to those racks anyway in your inner select). 您的SQL中的最后一行似乎没有必要,因为您再次选择ID为1的帐户的站点ID(并且您已经在内部选择中过滤到了这些机架)。

There may be something missing from this, as its hard to understand your exact domain without seeing the table definitions, but it seems likely you can improve the readability but more importantly the performance of your query with a few changes? 由于在没有看到表格定义的情况下难以理解您的确切域名,因此可能会遗漏一些内容,但您似乎可以提高可读性,但更重要的是,您可以通过一些更改来提高查询的性能?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM