2013-02-23 41 views
1

我有以下SELECT语句。SQL Server选择别名与IN语句不起作用

SELECT t.ID, 
     t.SiteID, 
     t.SpareID, 
     t.SpareLocationID, 
     t.Qty, 
     t.IsDefault 
    FROM TrainingDB.dbo.LocationsPerSpare t 
WHERE t.SpareID IN 
     (SELECT s.SpareID 
      FROM TrainingDB.dbo.LocationsPerSpare s 
     WHERE s.SpareLocationID = t.SpareLocationID 
      AND s.SpareID = t.SpareID 
     GROUP BY s.SpareID 
     HAVING COUNT(CONVERT(VARCHAR(36), s.SpareID)) > 2) 
ORDER BY t.SpareID 

如果我执行该脚本,它返回NULL。但是,如果我删除如下所示的t.别名,它将正常运行。

SELECT ID, 
     SiteID, 
     SpareID, 
     SpareLocationID, 
     Qty, 
     IsDefault 
    FROM TrainingDB.dbo.LocationsPerSpare 
WHERE SpareID IN 
     (SELECT s.SpareID 
      FROM TrainingDB.dbo.LocationsPerSpare s 
     WHERE s.SpareLocationID = SpareLocationID 
      AND s.SpareID = SpareID 
     GROUP BY s.SpareID 
     HAVING COUNT(CONVERT(VARCHAR(36), s.SpareID)) > 2) 
ORDER BY SpareID 

我觉得这很奇怪。有任何想法吗?

回答

1

您需要从子查询中删除

AND s.SpareID = t.SpareID 

。当SpareID尚未有值时,您正在使用子查询过滤主查询中SpareID的值。

+0

此外,我会补充说,第二个查询工作的原因是's.SpareID = SpareID'本质上是'1 = 1'。 SpareLocationID也一样。当然他们等同。 – 2013-02-23 20:24:24

+0

关闭。删除s.SpareLocationID = t.SpareLocationID的作品。感谢您的答复。令人费解的事情是,没有“t”。别名,它工作正常。 – 2013-02-23 20:28:49

+0

谢谢Nathan。我更频繁地使用Oracle,并且我没有这些问题。就像你说的那样,别名不会暗示1 = 1。但那是有用的知道。 – 2013-02-23 20:31:57

0

顺便问一下,你也可以重写此查询没有加入,利用窗口函数代替:

select lps.ID, lps.SiteID, lps.SpareID, lps.SpareLocationID, 
     lps.Qty, lps.IsDefault 
from (select lps.*, 
      count(*) over (partition by spareId) as SpareCnt 
     from TrainingDB.dbo.LocationsPerSpare lps 
    ) lps 
where SpareCnt > 2 

你需要的别名,是因为在一个子查询中的非混淆列在最近的分配表的原因参考。所以,

where s.SpareID = t.SpareID 

比较外部表引用和内部引用的SpareId。

where s.SpareID = SpareID 

首先确定SpareID来自哪个表。它匹配内部子查询中的列,因此它使用该列。表达式是等效于:

where s.SpareID = s.SpareId 

最后,的convertcount用户是完全不必要的。 Count仅计算非NULL值的数量,并且在转换为字符串时不会更改。

例如,当我测试此代码,它工作正常:

declare @t uniqueidentifier = newid(); 

select count(distinct t) 
from (select @t as t) v 

虽然,有趣的是,这个代码不上SQLFiddle工作。但是存在错误@t未定义,这是不相关的。

+0

非常有趣的戈登,谢谢你的回应。但是,SpareID是唯一标识符,我收到一条错误消息,迫使我使用CONVERT。 – 2013-02-24 14:11:14