我有以下SELECT
声明。
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
我发现这很奇怪。有什么想法吗?
答案 0 :(得分:1)
您需要删除
AND s.SpareID = t.SpareID
来自您的子查询的。当SpareID还没有值时,您正在使用子查询过滤主查询中的SpareID值。
答案 1 :(得分: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
最后,convert
count
的用户完全没必要。 Count
只计算非NULL值的数量,转换为字符串时不会改变。
例如,当我测试这段代码时,它运行正常:
declare @t uniqueidentifier = newid();
select count(distinct t)
from (select @t as t) v
虽然,有趣的是,这段代码不适用于SQLFiddle。但是有一个错误是@t
未定义,这是无关的。