【问题标题】:How to do WHERE clause BEFORE INNER JOIN如何在 INNER JOIN 之前执行 WHERE 子句
【发布时间】:2013-05-14 00:43:23
【问题描述】:

我如何进行这样的查询?

select Distinct  Station  , Slot , SubSlot, CompID , CompName 
from DeviceTrace as DT DT.DeviceID = '1339759958' 
inner join CompList as CL  
where  and DT.CompID = CL.CompID

在开始使用内部连接之前,我需要执行 DT.DeviceID = '1339759958'。 我使用 sql 服务器。

【问题讨论】:

  • SQL 语法不是这样工作的。并假设这些条款的运行方式与您编写它们的方式一样......充其量只是简单化。过滤很可能发生在连接条件之前(如果查询优化器很好并且统计数据指向该方向)。
  • Night Walker:如果您在使用此查询时遇到性能问题(例如,在 Nested Loop/Hash/Merge Join 之后有一个 Filter 运算符),您应该在其中发布执行计划和 DDL 语句(对于表和索引)结束当前问题后的另一个问题。
  • 似乎高级用户正在阅读这篇文章以了解查询优化器的详细信息。但看起来 OP 只是想过滤 DeviceID。不知道这怎么可能“没有建设性”。
  • @NightWalker 你能澄清一下这个问题吗?你需要什么以及为什么需要它? (是性能问题,代码优雅问题,还是其他问题……?)就目前而言,它不是很清楚,这会导致矛盾和扩展讨论。
  • “似乎”SELECT的语法(SELECT ... FROM ... WHERE ...)和逻辑执行顺序(FROM/"joins" > ON, WHERE, GROUP BY, ...)无法更改。

标签: sql sql-server inner-join


【解决方案1】:

我很难相信这有什么不同。如果查询优化器计算出这样做更有效,则应该在连接之前应用谓词。您可能需要这样做的唯一情况是优化器做出错误的选择(至少对于内部联接——外部联接存在有效情况)。

【讨论】:

  • 100% 同意!你不应该这样做;优化器会自动完成。因为您问了这个问题,我相信您不会使用提示和其他高级人员对您的请求进行手动优化。为了清楚起见,您的请求必须从 DeviceTrace 中选择 Distinct Station 、 Slot 、 SubSlot 、 CompID 、 CompName 作为 DT 内加入 CompList 作为 CL where 和 DT.CompID = CL.CompID 和 DT.DeviceID = '1339759958'
【解决方案2】:

尝试添加ON 子句。

SELECT DISTNCT Station, Slot, SubSlot, CompID, CompName 
FROM   DeviceTrace AS DT INNER JOIN CompList AS CL 
        ON  DT.CompID = CL.CompID AND
            DT.DeviceID = '1339759958'

在这种情况下,结果是相同的,因为您正在执行INNER JOIN。在 ON 子句中添加条件在执行 LEFT JOIN 并在右侧表上进行过滤时可能会有很大不同。

【讨论】:

  • 可能跑题了,但可以帮助您区分在ON 子句和WHERE 子句中添加条件。 CLICK here
【解决方案3】:

您可以使用子查询在join 之前应用where 子句:

select  *
from    (
        select  *
        from    DeviceTrace
        where   DeviceID = '1339759958' 
        ) as DT 
inner join 
        CompList as CL  
on      DT.CompID = CL.CompID

尽管在这种情况下,您是否过滤子查询、on 子句,甚至最后的 where 都无关紧要。

【讨论】:

  • -1 谬误。它不会“在 JOIN 之前应用 WHERE 子句”。 SQL Server 可以像查看 JOINed 视图中的查询一样轻松查看该子查询。
  • @RichardTheKiwi:优化器可以将查询重写为等效的其他查询。如答案的下半部分所述,我同意这些是等效的。不知道这如何使这个答案变得错误。
  • 答案 ("apply") 意味着用户可以使用提供的代码在 JOIN/ON 之前执行 WHERE 评估。你当然可以这样写,但首先应用它是一个谬误。此外,对于您是否只是澄清“结果行将相同”,下面的注释也含糊不清。
  • 听起来您正在阅读“应用”一词的意思是“强制优化器以下列方式执行查询”。我不确定这是在这种情况下最明显的阅读;)
  • 我不认为我的英语是世界上最好的,但是当你有一个问题context,并且回答说“你可以 使用.. 申请.. where.. before.. join”作为答案。你知道:)
【解决方案4】:

大卫·奥尔德里奇 (David Aldridge) 的一个小澄清。您必须使用查询

select Distinct  Station  , Slot , SubSlot, CompID , CompName 
from DeviceTrace as DT 
inner join CompList as CL on DT.CompID = CL.CompID  
where DT.DeviceID = '1339759958'

【讨论】:

    【解决方案5】:

    你可以试试这个:

    select Distinct Station, Slot, SubSlot, CompID, CompName 
    from (select * from DeviceTrace where DeviceID = '1339759958') as DT  
    inner join CompList as CL ON DT.CompID = CL.CompID
    

    【讨论】:

      猜你喜欢
      • 2012-04-25
      • 1970-01-01
      • 2013-08-11
      • 2010-11-04
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 2011-09-28
      • 1970-01-01
      相关资源
      最近更新 更多