SQL juntar-se: onde vs. cláusula de cláusula

votos
483

Depois de lê-lo, isto é não uma duplicata explícita vs SQL implícita junta . A resposta pode estar relacionado (ou mesmo o mesmo), mas a questão é diferente.


Qual é a diferença eo que deve ir em cada um?

Se eu entender a teoria corretamente, o otimizador de consulta deve ser capaz de usar ambos alternadamente.

Publicado 09/12/2008 em 21:14
fonte usuário
Em outras línguas...                            


14 respostas

votos
640

Eles não são a mesma coisa.

Considere estas perguntas:

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

e

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

A primeira vai devolver uma encomenda e as suas linhas, se qualquer, para o número de ordem 12345. O segundo irá retornar todas as ordens, mas apenas ordem 12345terá quaisquer linhas associados.

Com uma INNER JOIN, as cláusulas são efetivamente equivalente. No entanto, só porque eles são funcionalmente o mesmo, na medida em que produzem os mesmos resultados, não significa que os dois tipos de cláusulas têm o mesmo significado semântico.

Respondeu 09/12/2008 em 21:21
fonte usuário

votos
154
  • Não importa para associações internas
  • Questões para as junções externas

    uma. WHEREcláusula: Depois de aderir. Registros serão filtrados lugar depois de junção tomou.

    b. ONcláusula - Antes de se juntar. Registros (da tabela à direita) será filtrada antes de se juntar. Isso pode acabar como nulo no resultado (desde EXTERIOR juntar).



Exemplo : Considere as tabelas abaixo:

    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) Dentro WHEREcláusula:

  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) Dentro JOINcláusula

  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 | 
Respondeu 07/01/2014 em 21:54
fonte usuário

votos
137

No INNER JOINs eles são intercambiáveis, e o otimizador irá reorganizá-los à vontade.

No OUTER JOINs, eles não são necessariamente intercambiáveis, dependendo de qual lado da associação de que dependem.

Eu colocá-los em qualquer lugar, dependendo da legibilidade.

Respondeu 09/12/2008 em 21:21
fonte usuário

votos
30

A maneira que eu faço é:

Sempre coloque a condições de participar da cláusula ON Se você está fazendo uma junção interna, por isso não adicionar quaisquer condições em que a cláusula ON, colocá-los na cláusula WHERE

Se você está fazendo uma junção esquerda, adicione quaisquer condições em que a cláusula ON para a tabela no lado direito da junção. Isto é uma necessidade, porque a adição de uma cláusula de que referencia onde o lado direito da junção irá converter a juntar-se a uma junção interna (Com uma excepção descrito abaixo).

A exceção é que quando você está olhando para os registros que não estão em uma tabela particular, você adicionaria o refernce a um identificador único (que não é sempre null) na direita juntam-se a tabela com a cláusula de que desta forma "Onde t2. IDField é nulo". Assim, a única vez que você deve fazer referência a uma tabela no lado direito da junção é encontrar os registros que não estão na tabela.

Respondeu 09/12/2008 em 21:57
fonte usuário

votos
29

Em uma junção interna, eles significam a mesma coisa. No entanto, você vai obter resultados diferentes em uma junção externa, dependendo se você colocar a condição de junção em WHERE vs a cláusula ON. Dê uma olhada esta questão relacionada e essa resposta (por mim).

Eu acho que faz mais sentido para ter o hábito de sempre colocar a condição de junção na cláusula ON (a menos que seja uma junção externa e você realmente quer que ele na cláusula WHERE) pois torna-se mais clara para quem lê sua consulta que condições as tabelas estão sendo unidos, e também ajuda a prevenir a cláusula WHERE de ser dezenas de longas filas.

Respondeu 09/12/2008 em 21:20
fonte usuário

votos
12

Este artigo explica claramente a diferença. Ele também explica o "ON joined_condition vs ONDE joined_condition ou joined_alias é nulo".

A ONDE filtros cláusula tanto o esquerdo eo lado direito da junção, enquanto a cláusula ON sempre filtrar apenas o lado direito.

  1. Se você sempre quer buscar os registros do lado esquerdo e só Cadastre-se alguma condição corresponde então você deve a cláusula ON.
  2. Se você deseja filtrar o produto de unir ambos os lados, então você deve usar a cláusula WHERE.
Respondeu 25/05/2014 em 15:20
fonte usuário

votos
7

Em termos do otimizador, ele não deve fazer a diferença se você definir a sua juntar cláusulas com ON ou WHERE.

No entanto, IMHO, eu acho que é muito mais clara de usar a cláusula ON ao executar junta. Dessa forma você terá uma seção específica de você consulta que determina como a junção é tratado contra misturados com o resto das cláusulas WHERE.

Respondeu 09/12/2008 em 21:21
fonte usuário

votos
5

Há uma grande diferença entre onde cláusula vs. na cláusula , quando se trata de LEFT JOIN.

Aqui está um exemplo:

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

Há fid é id da tabela 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)

Consulta on "na cláusula":

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)

Consulta sobre "cláusula onde":

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)

É claro que, a primeira consulta retorna um registro de t1 e sua linha dependente de t2, se houver, para linha t1.v = 'K'.

A segunda consulta retorna linhas de T1, mas apenas para t1.v = 'K' terão qualquer linha associada a ele.

Respondeu 13/03/2016 em 06:31
fonte usuário

votos
1

Normalmente, a filtragem é processado na cláusula WHERE uma vez que as duas mesas já foram unidas. É possível, no entanto, que você pode querer filtrar uma ou ambas as tabelas antes de juntá-las. ou seja, a cláusula em que se aplica a todo o conjunto de resultados enquanto o em cláusula só se aplica ao se juntar em questão.

Respondeu 16/02/2018 em 05:29
fonte usuário

votos
1

por melhores tabelas de desempenho deve ter uma coluna especial indexado a ser usado para JOINS.

por isso, se a coluna você condição não é uma daquelas colunas indexadas, então eu suspeito que é melhor mantê-lo em WHERE.

para que você Cadastre-se usando as colunas indexadas, em seguida, depois de se juntar a você executar a condição na coluna nenhum indexado.

Respondeu 12/12/2014 em 21:10
fonte usuário

votos
0

Juntar-se para um interior, WHEREe ONpodem ser usados alternadamente. Na verdade, é possível usar ONem uma subconsulta correlacionada. Por exemplo:

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)
...
)

Este é (IMHO) totalmente confuso para um ser humano, e é muito fácil esquecer de ligar table1 para nada (porque a tabela "driver" não tem uma cláusula de "on"), mas é legal.

Respondeu 16/05/2014 em 23:40
fonte usuário

votos
0

Em SQL, a cláusula da 'onde' e 'ON', são uma espécie de condicional Statemants, mas a principal diferença entre eles é, 'Onde' Cláusula é utilizado em instruções SELECT / atualizar para especificar as condições, enquanto Cláusula o 'ON' é utilizado em junta, onde se verifica ou verifica se os registros são encontrados nas tabelas de destino e de origem, antes de as tabelas estão unidas

Por exemplo: - 'ONDE'

* SELECT FROM empregado ONDE employee_id = 101

Por exemplo: - 'ON'

* Há duas mesas de funcionários e employee_details, as colunas correspondentes são employee_id. *

SELECT * FROM EMPREGADOS INNER JOIN employee_details ON employee.employee_id = employee_details.employee_id

Espero ter respondido à sua Question.Revert volta para esclarecimentos.

Respondeu 05/02/2014 em 11:57
fonte usuário

votos
0

Eu acho que é o efeito se juntar a sequência. No canto superior esquerdo juntar caso, SQL não LEFT JOIN primeiro e depois fazer onde filtro. No caso Downer, encontrar Orders.ID = 12345 primeiro, e depois se juntam.

Respondeu 07/01/2014 em 04:49
fonte usuário

votos
-5

esta é a minha solução.

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

Você deve ter o GROUP BYpara fazê-lo funcionar.

Espero que isso ajuda.

Respondeu 26/04/2010 em 08:53
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more