Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/85.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 联接内的相关子查询?_Sql_Sql Server 2008_Subquery_Correlated Subquery - Fatal编程技术网

Sql 联接内的相关子查询?

Sql 联接内的相关子查询?,sql,sql-server-2008,subquery,correlated-subquery,Sql,Sql Server 2008,Subquery,Correlated Subquery,我有一个查询,其中我需要一个连接中的相关子查询。我说需要,我的意思是我想我需要它在那里。。。我该怎么做?我的查询如下,我得到了“多部分标识符”字段名出现在“无法绑定”错误。。。如何将此查询更改为有效 SELECT FireEvent.ExerciseID, FireEvent.FireEventID, tempHitEvent.HitEventID, FireEvent.AssociatedPlayerID, tempHitEven

我有一个查询,其中我需要一个连接中的相关子查询。我说需要,我的意思是我想我需要它在那里。。。我该怎么做?我的查询如下,我得到了“多部分标识符”字段名出现在“无法绑定”错误。。。如何将此查询更改为有效

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

交叉应用在这种情况下有效

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

交叉应用在这种情况下有效

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

您不需要相关子查询。您似乎有一个相对简单的连接,尽管同时在几个字段上

下面的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 

您不需要相关子查询。您似乎有一个相对简单的连接,尽管同时在几个字段上

下面的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 
使用而不是左连接。我不得不把你们的一些条款移走,但下面的内容应该会产生预期的结果

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的情况下返回结果,请使用
交叉应用
<代码>交叉应用是到
外部应用
什么
内部连接
是到
左侧连接


附录

这一切都可以通过使用联接来实现,而无需使用
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
与使用
外部应用
相比,这可能会稍微提高性能,但可能不会。这取决于您的模式和正在处理的数据量。测试是无法替代的:

使用而不是左连接。我不得不把你们的一些条款移走,但下面的内容应该会产生预期的结果

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的情况下返回结果,请使用
交叉应用
<代码>交叉应用是到
外部应用
什么
内部连接
是到
左侧连接


附录

这一切都可以通过使用联接来实现,而无需使用
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

与使用
外部应用
相比,这可能会稍微提高性能,但可能不会。这取决于您的模式和正在处理的数据量。测试是无法替代的:

这不起作用,通过应用子查询中的条件,选择
RANK
函数的结果。i、 e.通过使用外部应用,子查询将返回fireevent.EventTime的5秒钟内的第一个事件,但是,如果第一个HitEvent在fireevent时间的5秒钟内,则您的查询将只返回结果(存在细微但重要的差异)。我修改了查询,以便在rank()中使用更好的分区子句。这并不完全相同。但是,我认为您可以展开查询,只需获取子查询,添加另一列(使用窗口函数)来计算fire事件id,并完全取消外部连接。修改partion子句在一定程度上有所帮助,然而,一个基本问题仍然存在,即子查询的结果与主查询直接相关,因此需要相关子查询。为了更好地演示这个问题,我做了一个实验。在第二个结果窗格中,HitResult为空,因为第一个HitEvent不在FireEvent的5秒内。在top查询中,将显示5秒内的第一个HitEvent(HitResult=4,因为这发生在HitResult=5的行之前)。在窗口函数出现之前,所有相关子查询都可以编写为联接和分组。您的意思是需要在子查询中连接到FE。如果其中一个“应用”方法不起作用,您可以将其添加回。我并不是说使用相关子查询是唯一的方法,我要说的是,您发布的查询与问题中提出的逻辑(即fireevent 5秒内的第一个hitevent)的工作方式不同。这不起作用,通过应用子查询中的条件,选择
RANK
函数的结果。i、 e.通过使用外部应用,子查询将返回fireevent.EventTime的5秒钟内的第一个事件,但是,如果第一个HitEvent在fireevent时间的5秒钟内,则您的查询将只返回结果(存在细微但重要的差异)。我修改了查询,以便在rank()中使用更好的分区子句。这并不完全相同。但是,我认为您可以展开查询,只需获取子查询,添加另一列(使用窗口函数)来计算fire事件id,并完全取消外部连接。修改partion子句在一定程度上有所帮助,然而,一个基本问题仍然存在,即子查询的结果与主查询直接相关,因此需要相关子查询。为了更好地演示这个问题,我做了一个实验。在第二个结果窗格中,HitResult为空,因为第一个HitEvent不在FireEvent的5秒内。在顶部查询中,将显示5秒内的第一个HitEvent(带HitResult)