1

我有一个查询,我需要一个连接内的相关子查询。我说需要,我的意思是我认为我需要它......我该怎么做?我的查询如下,我收到“无法绑定多部分标识符“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
4

3 回答 3

5

使用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 APPLYOUTER APPLY什么INNER JOIN是什么LEFT JOIN


附录

这一切都可以使用不需要的连接来实现OUTER APPLY,方法是不使用子查询来连接 HitEvent,然后RANK对所有数据执行该功能,而不仅仅是 HitEvent 表。这一切都需要移动到子查询中,以便RANK函数的结果可以包含在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,但可能不会。这取决于您的架构和您正在处理的数据量。没有什么可以替代测试:

于 2012-05-30T08:20:49.547 回答
0

交叉应用适用于这种情况......

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
于 2012-05-30T02:11:06.733 回答
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 
于 2012-05-30T02:30:45.037 回答