SQL JOIN - WHERE clause vs. ON clause

前端 未结 19 1600
深忆病人
深忆病人 2020-11-21 11:56

After reading it, this is not a duplicate of Explicit vs Implicit SQL Joins. The answer may be related (or even the same) but the question is diffe

相关标签:
19条回答
  • 2020-11-21 12:48

    They are not the same thing.

    Consider these queries:

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

    and

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

    The first will return an order and its lines, if any, for order number 12345. The second will return all orders, but only order 12345 will have any lines associated with it.

    With an INNER JOIN, the clauses are effectively equivalent. However, just because they are functionally the same, in that they produce the same results, does not mean the two kinds of clauses have the same semantic meaning.

    0 讨论(0)
  • 2020-11-21 12:48

    There is great difference between where clause vs. on clause, when it comes to left join.

    Here is example:

    mysql> desc t1; 
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | NO   |     | NULL    |       |
    | fid   | int(11)     | NO   |     | NULL    |       |
    | v     | varchar(20) | NO   |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    

    There fid is id of table t2.

    mysql> desc t2;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | NO   |     | NULL    |       |
    | v     | varchar(10) | NO   |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    

    Query on "on clause" :

    mysql> SELECT * FROM `t1` left join t2 on fid = t2.id AND t1.v = 'K' 
        -> ;
    +----+-----+---+------+------+
    | id | fid | v | id   | v    |
    +----+-----+---+------+------+
    |  1 |   1 | H | NULL | NULL |
    |  2 |   1 | B | NULL | NULL |
    |  3 |   2 | H | NULL | NULL |
    |  4 |   7 | K | NULL | NULL |
    |  5 |   5 | L | NULL | NULL |
    +----+-----+---+------+------+
    5 rows in set (0.00 sec)
    

    Query on "where clause":

    mysql> SELECT * FROM `t1` left join t2 on fid = t2.id where t1.v = 'K';
    +----+-----+---+------+------+
    | id | fid | v | id   | v    |
    +----+-----+---+------+------+
    |  4 |   7 | K | NULL | NULL |
    +----+-----+---+------+------+
    1 row in set (0.00 sec)
    

    It is clear that, the first query returns a record from t1 and its dependent row from t2, if any, for row t1.v = 'K'.

    The second query returns rows from t1, but only for t1.v = 'K' will have any associated row with it.

    0 讨论(0)
  • 2020-11-21 12:49

    For an inner join, WHERE and ON can be used interchangeably. In fact, it's possible to use ON in a correlated subquery. For example:

    update mytable
    set myscore=100
    where exists (
    select 1 from table1
    inner join table2
    on (table2.key = mytable.key)
    inner join table3
    on (table3.key = table2.key and table3.key = table1.key)
    ...
    )
    

    This is (IMHO) utterly confusing to a human, and it's very easy to forget to link table1 to anything (because the "driver" table doesn't have an "on" clause), but it's legal.

    0 讨论(0)
  • 2020-11-21 12:54

    Are you trying to join data or filter data?

    For readability it makes the most sense to isolate these use cases to ON and WHERE respectively.

    • join data in ON
    • filter data in WHERE

    It can become very difficult to read a query where the JOIN condition and a filtering condition exist in the WHERE clause.

    Performance wise you should not see a difference, though different types of SQL sometimes handle query planning differently so it can be worth trying ¯\_(ツ)_/¯ (Do be aware of caching effecting the query speed)

    Also as others have noted, if you use an outer join you will get different results if you place the filter condition in the ON clause because it only effects one of the tables.

    I wrote a more in depth post about this here: https://dataschool.com/learn/difference-between-where-and-on-in-sql

    0 讨论(0)
  • 2020-11-21 12:54

    this is my solution.

    SELECT song_ID,songs.fullname, singers.fullname
    FROM music JOIN songs ON songs.ID = music.song_ID  
    JOIN singers ON singers.ID = music.singer_ID
    GROUP BY songs.fullname
    

    You must have the GROUP BY to get it to work.

    Hope this help.

    0 讨论(0)
  • 2020-11-21 12:56

    On INNER JOINs they are interchangeable, and the optimizer will rearrange them at will.

    On OUTER JOINs, they are not necessarily interchangeable, depending on which side of the join they depend on.

    I put them in either place depending on the readability.

    0 讨论(0)
提交回复
热议问题