SQL连接:where子句与on子句

阅读后,这不是显式与隐式SQL联接的重复。 答案可能相关(甚至相同),但问题不同。


各有什么区别和应该怎么做?

如果我理解正确,那么查询优化器应该可以互换使用。


它们不是同一件事。

考虑这些查询:

SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID
WHERE Orders.ID = 12345

SELECT *
FROM Orders
LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID 
    AND Orders.ID = 12345

第一个将返回订单及其订单号(如果有),订单号12345 。 第二个将返回所有订单,但只有订单12345将有任何与其关联的行。

通过INNER JOIN ,这些条款实际上是等效的。 然而,仅仅因为它们在功能上是相同的,因为它们产生相同的结果,并不意味着这两种子句具有相同的语义含义。


  • 内连接无关紧要
  • 外连接的问题

    一个。 WHERE子句:加盟 。 记录将在联接发生后被过滤。

    ON条款 - 加入 。 记录(来自右表)将在加入前被过滤。 这可能会以结果为空(因为外部连接)。



  • 示例 :考虑下表:

        1. documents:
         | id    | name        |
         --------|-------------|
         | 1     | Document1   |
         | 2     | Document2   |
         | 3     | Document3   |
         | 4     | Document4   |
         | 5     | Document5   |
    
    
        2. downloads:
         | id   | document_id   | username |
         |------|---------------|----------|
         | 1    | 1             | sandeep  |
         | 2    | 1             | simi     |
         | 3    | 2             | sandeep  |
         | 4    | 2             | reya     |
         | 5    | 3             | simi     |
    

    a) WHERE子句内:

      SELECT documents.name, downloads.id
        FROM documents
        LEFT OUTER JOIN downloads
          ON documents.id = downloads.document_id
        WHERE username = 'sandeep'
    
     For above query the intermediate join table will look like this.
    
        | id(from documents) | name         | id (from downloads) | document_id | username |
        |--------------------|--------------|---------------------|-------------|----------|
        | 1                  | Document1    | 1                   | 1           | sandeep  |
        | 1                  | Document1    | 2                   | 1           | simi     |
        | 2                  | Document2    | 3                   | 2           | sandeep  |
        | 2                  | Document2    | 4                   | 2           | reya     |
        | 3                  | Document3    | 5                   | 3           | simi     |
        | 4                  | Document4    | NULL                | NULL        | NULL     |
        | 5                  | Document5    | NULL                | NULL        | NULL     |
    
      After applying the `WHERE` clause and selecting the listed attributes, the result will be: 
    
       | name         | id |
       |--------------|----|
       | Document1    | 1  |
       | Document2    | 3  | 
    

    b)内部JOIN子句

      SELECT documents.name, downloads.id
      FROM documents
        LEFT OUTER JOIN downloads
          ON documents.id = downloads.document_id
            AND username = 'sandeep'
    
    For above query the intermediate join table will look like this.
    
        | id(from documents) | name         | id (from downloads) | document_id | username |
        |--------------------|--------------|---------------------|-------------|----------|
        | 1                  | Document1    | 1                   | 1           | sandeep  |
        | 2                  | Document2    | 3                   | 2           | sandeep  |
        | 3                  | Document3    | NULL                | NULL        | NULL     |
        | 4                  | Document4    | NULL                | NULL        | NULL     |
        | 5                  | Document5    | NULL                | NULL        | NULL     |
    
    Notice how the rows in `documents` that did not match both the conditions are populated with `NULL` values.
    
    After Selecting the listed attributes, the result will be: 
    
       | name       | id   |
       |------------|------|
       |  Document1 | 1    |
       |  Document2 | 3    | 
       |  Document3 | NULL |
       |  Document4 | NULL | 
       |  Document5 | NULL | 
    

    INNER JOIN它们是可以互换的,优化器会随意重新排列它们。

    OUTER JOIN ,它们不一定是可以互换的,这取决于它们所依赖的连接的哪一侧。

    我根据可读性将它们放在任何一个地方。

    链接地址: http://www.djcxy.com/p/44021.html

    上一篇: SQL join: where clause vs. on clause

    下一篇: NOT IN clause and NULL values