我有一个查询,我需要在连接中使用相关子查询。我说需要,我的意思是我认为我需要它......我怎么能这样做?我的查询如下,我得到“多部分标识符”FIELDNAME GOES HERE“无法绑定”错误...如何更改此查询才能生效?
SELECT FireEvent.ExerciseID,
FireEvent.FireEventID,
tempHitEvent.HitEventID,
FireEvent.AssociatedPlayerID,
tempHitEvent.AssociatedPlayerID,
FireEvent.EventTime,
tempHitEvent.EventTime,
FireEvent.Longitude,
FireEvent.Latitude,
tempHitEvent.Longitude,
tempHitEvent.Latitude,
tempHitEvent.HitResult,
FireEvent.AmmunitionCode,
FireEvent.AmmunitionSource,
FireEvent.FireEventID,
0 AS 'IsArtillery'
FROM FireEvent
LEFT JOIN (SELECT HitEvent.*,
FireEvent.FireEventID,
Rank()
OVER (
ORDER BY HitEvent.EventTime) AS RankValue
FROM HitEvent
WHERE FireEvent.EventTime BETWEEN
Dateadd(millisecond, -5000,
HitEvent.EventTime) AND
Dateadd(millisecond,
5000, HitEvent.EventTime) AND HitEvent.FiringPlayerID = FireEvent.PlayerID
AND HitEvent.AmmunitionCode =
FireEvent.AmmunitionCode
AND HitEvent.ExerciseID =
'D289D508-1479-4C17-988C-5F6A847AE51E'
AND FireEvent.ExerciseID =
'D289D508-1479-4C17-988C-5F6A847AE51E'
AND HitEvent.HitResult NOT IN ( 0, 1 ) ) AS
tempHitEvent
ON (
RankValue = 1
AND tempHitEvent.FireEventID =
FireEvent.FireEventID
)
WHERE FireEvent.ExerciseID = 'D289D508-1479-4C17-988C-5F6A847AE51E'
ORDER BY HitEventID
答案 0 :(得分:2)
使用OUTER APPLY代替LEFT JOIN。我不得不移动你的一些条款,但下面应该产生所需的结果
SELECT FireEvent.ExerciseID,
FireEvent.FireEventID,
tempHitEvent.HitEventID,
FireEvent.AssociatedPlayerID,
tempHitEvent.AssociatedPlayerID,
FireEvent.EventTime,
tempHitEvent.EventTime,
FireEvent.Longitude,
FireEvent.Latitude,
tempHitEvent.Longitude,
tempHitEvent.Latitude,
tempHitEvent.HitResult,
FireEvent.AmmunitionCode,
FireEvent.AmmunitionSource,
FireEvent.FireEventID,
0 AS 'IsArtillery'
FROM FireEvent
OUTER APPLY
( SELECT HitEvent.*, RANK() OVER (ORDER BY HitEvent.EventTime) AS RankValue
FROM HitEvent
WHERE HitEvent.FireEventID = FireEvent.FireEventID
AND FireEvent.EventTime BETWEEN DATEADD(MILLISECOND, -5000, HitEvent.EventTime) AND DATEADD(MILLISECOND, 5000, HitEvent.EventTime)
AND HitEvent.FiringPlayerID = FireEvent.PlayerID
AND HitEvent.AmmunitionCode = FireEvent.AmmunitionCode
AND HitEvent.ExerciseID = FireEvent.ExerciseID
AND HitEvent.HitResult NOT IN ( 0, 1 )
) AS tempHitEvent
WHERE COALESCE(RankValue, 1) = 1
AND FireEvent.ExerciseID = 'D289D508-1479-4C17-988C-5F6A847AE51E'
ORDER BY FireEvent.HitEventID
如果您只想返回匹配HitEvent的结果,请使用CROSS APPLY
。 CROSS APPLY
OUTER APPLY
INNER JOIN
与LEFT JOIN
的对象是OUTER APPLY
。
<强>附录强>
这可以通过不使用RANK
的连接来实现,通过不使用子查询来连接HitEvent,然后对所有数据执行RANK
函数,而不仅仅是HitEvent表。这一切都需要移动到子查询,因此WHERE
函数的结果可以包含在SELECT *
FROM ( SELECT FireEvent.ExerciseID,
FireEvent.FireEventID,
HitEvent.HitEventID,
FireEvent.AssociatedPlayerID,
--HitEvent.AssociatedPlayerID,
FireEvent.EventTime,
HitEvent.EventTime [HitEventTime],
FireEvent.Longitude [FireEventLongitute],
FireEvent.Latitude [FireEventLatitute],
HitEvent.Longitude [HitEventLongitute],
HitEvent.Latitude [HitEventLatitute],
HitEvent.HitResult ,
FireEvent.AmmunitionCode,
FireEvent.AmmunitionSource,
0 [IsArtillery],
RANK() OVER(PARTITION BY HitEvent.FireEventID, HitEvent.FiringPlayerID, HitEvent.AmmunitionCode,HitEvent.ExerciseID ORDER BY HitEvent.EventTime) [RankValue]
FROM FireEvent
LEFT JOIN HitEvent
ON HitEvent.FireEventID = FireEvent.FireEventID
AND FireEvent.EventTime BETWEEN DATEADD(MILLISECOND, -5000, HitEvent.EventTime) AND DATEADD(MILLISECOND, 5000, HitEvent.EventTime)
AND HitEvent.FiringPlayerID = FireEvent.PlayerID
AND HitEvent.AmmunitionCode = FireEvent.AmmunitionCode
AND HitEvent.ExerciseID = FireEvent.ExerciseID
AND HitEvent.HitResult NOT IN ( 0, 1 )
) data
WHERE RanKValue = 1
子句中。
OUTER APPLY
与使用{{1}}相比,这可能会略微提高性能,但可能不会。这取决于您的架构和您正在处理的数据量。测试无可替代:
答案 1 :(得分:0)
Cross Apply适用于此场景......
SELECT FireEvent.ExerciseID,
FireEvent.FireEventID,
tempHitEvent.HitEventID,
FireEvent.AssociatedPlayerID,
tempHitEvent.AssociatedPlayerID,
FireEvent.EventTime,
tempHitEvent.EventTime,
FireEvent.Longitude,
FireEvent.Latitude,
tempHitEvent.Longitude,
tempHitEvent.Latitude,
tempHitEvent.HitResult,
FireEvent.AmmunitionCode,
FireEvent.AmmunitionSource,
FireEvent.FireEventID,
0 AS 'IsArtillery'
,RankValue
FROM FireEvent
CROSS APPLY (SELECT HitEvent.*,
FireEvent.FireEventID,
Rank()
OVER (
ORDER BY HitEvent.EventTime) AS RankValue
FROM HitEvent
WHERE FireEvent.EventTime BETWEEN
Dateadd(millisecond, -5000,
HitEvent.EventTime) AND
Dateadd(millisecond,
5000, HitEvent.EventTime) AND HitEvent.FiringPlayerID = FireEvent.PlayerID
AND HitEvent.AmmunitionCode =
FireEvent.AmmunitionCode
AND HitEvent.ExerciseID =
'D289D508-1479-4C17-988C-5F6A847AE51E'
AND FireEvent.ExerciseID =
'D289D508-1479-4C17-988C-5F6A847AE51E'
AND HitEvent.HitResult NOT IN ( 0, 1 ) )
tempHitEvent
WHERE
RankValue = 1
AND tempHitEvent.FireEventID =
FireEvent.FireEventID
AND FireEvent.ExerciseID = 'D289D508-1479-4C17-988C-5F6A847AE51E'
ORDER BY HitEventID
答案 2 :(得分:0)
您不需要相关子查询。你似乎有一个相对简单的联接,虽然同时在几个领域。
以下FROM子句从子查询内部提取引用两个表的条件,并将它们移到JOIN子句外部。这接近你想要的,取决于排名中的分区是否正在按预期执行:
FROM FireEvent fe left outer join
(SELECT HitEvent.*,
Rank() OVER (partition by FiringPlayerID, ExerciseID, FireEventID, FireEventID
ORDER BY HitEvent.EventTime) AS RankValue
FROM HitEvent
WHERE HitEvent.ExerciseID = 'D289D508-1479-4C17-988C-5F6A847AE51E' AND
HitEvent.HitResult NOT IN ( 0, 1 )
) he
ON he.FiringPlayerID = fe.PlayerId and
he.AmmunitionCode = fe.AmmunitionCode and
fe.EventTime BETWEEN Dateadd(millisecond, -5000, he.EventTime) AND
Dateadd(millisecond, 5000, he.EventTime) AND
fe.ExerciseID = 'D289D508-1479-4C17-988C-5F6A847AE51E' AND
RankValue = 1 , d
he.FireEventID = fe.FireEventID