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


17 respostas

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

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

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
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
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
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
0

Eu acho que essa distinção pode ser melhor explicada através da ordem lógica das operações em SQL , que é, simplificado:

  • FROM (Incluindo junta)
  • WHERE
  • GROUP BY
  • agregações
  • HAVING
  • WINDOW
  • SELECT
  • DISTINCT
  • UNION, INTERSECT,EXCEPT
  • ORDER BY
  • OFFSET
  • FETCH

Junta não são uma cláusula da instrução SELECT, mas um operador dentro FROM. Como tal, todas as ONcláusulas que pertencem ao correspondente JOINoperador tem "já aconteceu" logicamente pelo tempo de processamento lógico atinge a WHEREcláusula. Isto significa que, no caso de um LEFT JOIN, por exemplo, a junção externa da semântica já aconteceu no momento em que a WHEREcláusula é aplicada.

Eu expliquei o exemplo a seguir mais em profundidade neste post . Ao executar esta consulta:

SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
WHERE film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;

O LEFT JOINrealmente não tem qualquer efeito útil, porque, mesmo se um ator não jogar em um filme, o ator será filtrada, como FILM_IDserá NULLeo WHEREcláusula irá filtrar tal linha. O resultado é algo como:

ACTOR_ID  FIRST_NAME  LAST_NAME  COUNT
--------------------------------------
194       MERYL       ALLEN      1
198       MARY        KEITEL     1
30        SANDRA      PECK       1
85        MINNIE      ZELLWEGER  1
123       JULIANNE    DENCH      1

Ou seja, como se nós interior juntou as duas tabelas. Se mover o predicado de filtro na ONcláusula, torna-se agora um critério para a junção externa:

SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
FROM actor a
LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
  AND film_id < 10
GROUP BY a.actor_id, a.first_name, a.last_name
ORDER BY count(fa.film_id) ASC;

Ou seja, o resultado será conter agentes sem quaisquer filmes, ou sem qualquer filmes FILM_ID < 10

ACTOR_ID  FIRST_NAME  LAST_NAME     COUNT
-----------------------------------------
3         ED          CHASE         0
4         JENNIFER    DAVIS         0
5         JOHNNY      LOLLOBRIGIDA  0
6         BETTE       NICHOLSON     0
...
1         PENELOPE    GUINESS       1
200       THORA       TEMPLE        1
2         NICK        WAHLBERG      1
198       MARY        KEITEL        1

Em resumo

Sempre coloque o seu predicado onde faz mais sentido, logicamente.

Respondeu 09/04/2019 em 13:37
fonte usuário

votos
0

Vamos considerar essas tabelas:

UMA

id | SomeData

B

id | id_A | SomeOtherData

id_A sendo uma chave estrangeira para a tabela A

Escrevendo esta consulta:

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A;

Irá fornecer este resultado:

/ : part of the result
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////+-------+-------------------------+
|/////////////////////////////|
+-----------------------------+

O que está em A, mas não em B significa que não há valores nulos para B.


Agora, vamos considerar uma parte específica em B.id_A, e destacá-lo a partir do resultado anterior:

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|///////|                         |
|/////////////////////|///////|                         |
|/////////////////////+---+///|                         |
|/////////////////////|***|///|                         |
|/////////////////////+---+---+-------------------------+
|/////////////////////////////|
+-----------------------------+

Escrevendo esta consulta:

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A
AND B.id_A = SpecificPart;

Irá fornecer este resultado:

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|/////////////////////|       |                         |
|/////////////////////|       |                         |
|/////////////////////+---+   |                         |
|/////////////////////|***|   |                         |
|/////////////////////+---+---+-------------------------+
|/////////////////////////////|
+-----------------------------+

Porque este remove na junção interna os valores que não estão em B.id_A = SpecificPart


Agora, vamos alterar a consulta a esta:

SELECT *
FROM A
LEFT JOIN B
ON A.id = B.id_A
WHERE B.id_A = SpecificPart;

O resultado é agora:

/ : part of the result
* : part of the result with the specific B.id_A
                                       B
                      +---------------------------------+
            A         |                                 |
+---------------------+-------+                         |
|                     |       |                         |
|                     |       |                         |
|                     +---+   |                         |
|                     |***|   |                         |
|                     +---+---+-------------------------+
|                             |
+-----------------------------+

Uma vez que todo o resultado é filtrada contra B.id_A = SpecificParta remoção das peças B.id_A = NULL, que estão na A, que não estão em B

Respondeu 12/04/2019 em 10:03
fonte usuário

votos
0

Você está tentando juntar dados de dados ou filtro?

Para facilitar a leitura que faz mais sentido para isolar esses casos de uso para ON e onde, respectivamente.

  • juntar dados em ON
  • dados de filtro em ONDE

Ela pode se tornar muito difícil de ler uma consulta onde a condição JOIN e uma condição de filtragem existe na cláusula WHERE.

Em termos de desempenho, você não deve ver uma diferença, embora diferentes tipos de SQL, por vezes, lidar com planejamento consulta de maneira diferente para que ele possa valer a pena tentar ¯\_(ツ)_/¯(Esteja ciente de cache efetuar a velocidade de consulta)

Também como os outros, se você usar uma associação externa que você vai obter resultados diferentes se você colocar a condição de filtro na cláusula ON porque só efeitos de uma das mesas.

Eu escrevi um mais em pós profundidade sobre isso aqui: https://dataschool.com/learn/difference-between-where-and-on-in-sql

Respondeu 30/04/2019 em 02:17
fonte usuário

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