代码之家  ›  专栏  ›  技术社区  ›  daniel_aren

WHERE子句中的筛选与ON子句中的过滤有什么区别?

  •  4
  • daniel_aren  · 技术社区  · 12 年前

    我想知道在使用WHERE子句或在内部联接的ON中使用匹配是否有任何区别。

    这种情况下的结果是一样的。

    第一个查询:

    with Catmin as 
    (
        select categoryid, MIN(unitprice) as mn
        from production.Products
        group by categoryid
    ) 
    select p.productname, mn
    from Catmin 
    inner join Production.Products p
    on p.categoryid = Catmin.categoryid
    and p.unitprice = Catmin.mn;
    

    第二个查询:

    with Catmin as 
    (
        select categoryid, MIN(unitprice) as mn
        from production.Products
        group by categoryid
    ) 
    select p.productname, mn
    from Catmin 
    inner join Production.Products p
    on p.categoryid = Catmin.categoryid
    where p.unitprice = Catmin.mn;          // this is changed
    

    两个查询的结果:

    result

    3 回复  |  直到 12 年前
        1
  •  6
  •   Ricardo C. zero    12 年前

    我的回答可能有点离题,但我想强调一个问题,当您将INNER JOIN转换为OUTER JOIN时,可能会出现这个问题。

    在这种情况下,将谓词(测试条件)放在on或WHERE子句上最重要的区别在于,您可以 在没有注意到的情况下将左或右外部联接转为内部联接 ,如果在WHERE子句中放置要省略的表的字段。

    例如,在表a和B之间的LEFT JOIN中,如果在WHERE子句中包含一个涉及B字段的条件,那么很有可能在结果集中没有从B返回的空行。有效地,并且隐含地,您将LEFT JOIN变成了INNER JOIN。

    另一方面,如果在On子句中包含相同的测试,则将继续返回空行。

    例如,以下面的查询为例:

    SELECT * FROM A 
    LEFT JOIN B
       ON A.ID=B.ID
    

    查询还将从A返回与任何B都不匹配的行。

    接受第二个查询:

    SELECT * FROM A 
    LEFT JOIN B
    WHERE A.ID=B.ID
    

    第二个查询不会从A返回任何与B不匹配的行,即使您认为会返回,因为您指定了LEFT JOIN。这是因为测试A.ID=B.ID将在结果集中遗漏任何B.ID为null的行。

    这就是为什么我喜欢把谓词放在ON子句中,而不是放在WHERE子句中。

        2
  •  5
  •   Ouscux    12 年前

    结果完全相同。 由于查询性能的提高,更建议使用“ON”子句。

    通过使用on子句,您可以先筛选第一个数据集,然后将数据连接到其他表,而不是先从表中请求数据,然后再进行筛选。因此,需要匹配的数据更少,结果更快。

        3
  •  3
  •   Sai Avinash    10 年前

    以上两个查询输出之间没有区别 两者的结果相同 .

    使用On子句时,联接操作只联接那些与上指定的编码匹配的行 ON 条款

    如有 Where 子句,联接操作联接所有行,然后根据指定的条件进行筛选

    因此,显然On Clause更有效,应该优先于where condition