Solución:
La respuesta es NO diferencia, pero:
Siempre preferiré hacer lo siguiente.
- Mantenga siempre el Condiciones de unión en
ON
cláusula - Pon siempre el filtro en
where
cláusula
Esto hace que la consulta sea más legible.
Entonces usaré esta consulta:
SELECT value
FROM table1
INNER JOIN table2
ON table1.id = table2.id
WHERE table1.id = 1
Sin embargo, cuando estás usando OUTER JOIN'S
Hay una gran diferencia en mantener el filtro en el ON
condición y Where
condición.
Procesamiento de consultas lógicas
La siguiente lista contiene una forma general de consulta, junto con los números de paso asignados según el orden en el que se procesan lógicamente las diferentes cláusulas.
(5) SELECT (5-2) DISTINCT (5-3) TOP(<top_specification>) (5-1) <select_list>
(1) FROM (1-J) <left_table> <join_type> JOIN <right_table> ON <on_predicate>
| (1-A) <left_table> <apply_type> APPLY <right_table_expression> AS <alias>
| (1-P) <left_table> PIVOT(<pivot_specification>) AS <alias>
| (1-U) <left_table> UNPIVOT(<unpivot_specification>) AS <alias>
(2) WHERE <where_predicate>
(3) GROUP BY <group_by_specification>
(4) HAVING <having_predicate>
(6) ORDER BY <order_by_list>;
Procesamiento de consultas lógicas de diagrama de flujo
-
(1) FROM: La fase FROM identifica las tablas de origen de la consulta y procesa los operadores de tabla. Cada operador de tabla aplica una serie de subfases. Por ejemplo, las fases involucradas en una unión son (1-J1) Producto cartesiano, (1-J2) Filtro activado, (1-J3) Agregar filas externas. La fase FROM genera la tabla virtual VT1.
-
(1-J1) Producto cartesiano: Esta fase realiza un producto cartesiano (unión cruzada) entre las dos tablas involucradas en el operador de tabla, generando VT1-J1.
- (1-J2) Activar filtro: Esta fase filtra las filas de VT1-J1 según el predicado que aparece en la cláusula ON (
). Solo las filas para las que el predicado se evalúa como TRUE se insertan en VT1-J2. - (1-J3) Agregar filas externas: Si se especifica OUTER JOIN (a diferencia de CROSS JOIN o INNER JOIN), las filas de la tabla preservada o las tablas para las que no se encontró una coincidencia se agregan a las filas de VT1-J2 como filas externas, generando VT1-J3.
- (2) DÓNDE: Esta fase filtra las filas de VT1 según el predicado que aparece en la cláusula WHERE (). Solo las filas para las que el predicado se evalúa como TRUE se insertan en VT2.
- (3) GROUP BY: Esta fase organiza las filas de VT2 en grupos según la lista de columnas especificada en la cláusula GROUP BY, generando VT3. En última instancia, habrá una fila de resultados por grupo.
- (4) HAVING: Esta fase filtra los grupos de VT3 en función del predicado que aparece en la cláusula HAVING (
). Solo los grupos para los que el predicado se evalúa como TRUE se insertan en VT4. - (5) SELECT: Esta fase procesa los elementos en la cláusula SELECT, generando VT5.
- (5-1) Evaluar Expresiones: Esta fase evalúa las expresiones en la lista SELECT, generando VT5-1.
- (5-2) DISTINCT: Esta fase elimina filas duplicadas de VT5-1, generando VT5-2.
- (5-3) TOP: Esta fase filtra el número superior especificado o el porcentaje de filas de VT5-2 basado en el orden lógico definido por la cláusula ORDER BY, generando la tabla VT5-3.
- (6) ORDER BY: Esta fase ordena las filas de VT5-3 según la lista de columnas especificada en la cláusula ORDER BY, generando el cursor VC6.
se refiere a libro “Consulta T-SQL (referencia para desarrolladores) ”
Si bien no hay diferencia al usar UNIONES INTERNAS, como señaló VR46, hay una diferencia significativa al usar UNIONES EXTERIORES y evaluar un valor en la segunda tabla (para combinaciones a la izquierda – primera tabla para combinaciones a la derecha). Considere la siguiente configuración:
DECLARE @Table1 TABLE ([ID] int)
DECLARE @Table2 TABLE ([Table1ID] int, [Value] varchar(50))
INSERT INTO @Table1
VALUES
(1),
(2),
(3)
INSERT INTO @Table2
VALUES
(1, 'test'),
(1, 'hello'),
(2, 'goodbye')
Si lo seleccionamos usando una combinación externa izquierda y ponemos una condición en la cláusula where:
SELECT * FROM @Table1 T1
LEFT OUTER JOIN @Table2 T2
ON T1.ID = T2.Table1ID
WHERE T2.Table1ID = 1
Obtenemos los siguientes resultados:
ID Table1ID Value
----------- ----------- --------------------------------------------------
1 1 test
1 1 hello
Esto se debe a que la cláusula where limita el conjunto de resultados, por lo que solo incluimos registros de la tabla1 que tienen un ID de 1. Sin embargo, si movemos la condición a la cláusula on:
SELECT * FROM @Table1 T1
LEFT OUTER JOIN @Table2 T2
ON T1.ID = T2.Table1ID
AND T2.Table1ID = 1
Obtenemos los siguientes resultados:
ID Table1ID Value
----------- ----------- --------------------------------------------------
1 1 test
1 1 hello
2 NULL NULL
3 NULL NULL
Esto se debe a que ya no estamos filtrando el conjunto de resultados por el ID de 1 de la tabla1, sino que estamos filtrando el JOIN. Entonces, aunque el ID de 2 de la tabla1 tiene una coincidencia en la segunda tabla, se excluye de la combinación, pero NO del conjunto de resultados (de ahí los valores nulos).
Por lo tanto, para las combinaciones internas no importa, pero debe mantenerlo en la cláusula where para mayor legibilidad y coherencia. Sin embargo, para las combinaciones externas, debe tener en cuenta que SÍ importa dónde coloque la condición, ya que afectará su conjunto de resultados.
Creo que la respuesta marcada como “correcta” no es correcta. ¿Por qué? Trato de explicar:
Tenemos opinión
“Mantenga siempre las condiciones de combinación en la cláusula ON Siempre coloque los filtros en la cláusula where”
Y esto está mal. Si está en unión interna, cada vez coloque los parámetros de filtro en la cláusula ON, no en where. ¿Usted pregunta por qué? Intente imaginar una consulta compleja con un total de 10 tablas (por ejemplo, cada tabla tiene 10k recs) unirse, con una cláusula WHERE compleja (por ejemplo, funciones o cálculos utilizados). Si coloca criterios de filtrado en la cláusula ON, no se produce JOINS entre estas 10 tablas, la cláusula WHERE no se ejecutará en absoluto. En este caso, no está realizando 10000 ^ 10 cálculos en la cláusula WHERE. Esto tiene sentido, no poner parámetros de filtrado solo en la cláusula WHERE.