Supongo que siempre he supuesto que las funciones escalares en la parte seleccionada de una consulta SQL solo se aplicarán a las filas que cumplan con todos los criterios de la cláusula where.¿Se pueden aplicar las funciones escalares antes de filtrar cuando se ejecuta una instrucción SQL?
Hoy estaba depurando un código de un proveedor y tuve esa suposición cuestionada. La única razón por la que se me ocurre la falla de este código es que se llama a la función Substring() a los datos que deberían haber sido filtrados por la cláusula WHERE. Pero parece que la llamada de subcadena se está aplicando antes de que ocurra el filtrado, la consulta está fallando. Aquí hay un ejemplo de lo que quiero decir. Digamos que tenemos dos tablas, cada una con 2 columnas y con 2 filas y 1 fila respectivamente. La primera columna en cada una es solo una identificación. NAME es solo una cadena, y NAME_LENGTH nos dice cuántos caracteres en el nombre con la misma ID. Tenga en cuenta que solo los nombres con más de un carácter tienen una fila correspondiente en la tabla LONG_NAMES.
NAMES: ID, NAME
1, "Peter"
2, "X"
LONG_NAMES: ID, NAME_LENGTH
1, 5
Si quiero una consulta para imprimir los nombres con los últimos 3 letras cortadas, por primera vez podría intentar algo como esto (suponiendo sintaxis de SQL Server por ahora):
SELECT substring(NAME,1,len(NAME)-3)
FROM NAMES;
lo haría pronto descubro que esto me daría un error, porque cuando llegue a "X" intentará usar un número negativo para en la llamada de subcadena, y fallará. La forma en que mi proveedor decidió resolver esto fue filtrando las filas donde las cadenas eran demasiado cortas para que la consulta de len 3 funcionara. Lo hizo mediante la unión a otra tabla:
SELECT substring(NAMES.NAME,1,len(NAMES.NAME)-3)
FROM NAMES
INNER JOIN LONG_NAMES
ON NAMES.ID = LONG_NAMES.ID;
A primera vista, esta consulta parece que podría trabajar. La condición de unión eliminará cualquier fila que tenga campos NAME suficientemente cortos para que falle la llamada de subcadena.
Sin embargo, de lo que puedo observar, SQL Server veces tratan de calcular la expresión de la subcadena para todo en la mesa, y luego aplicar la unión de filtrar filas. ¿Se supone que esto sucederá de esta manera? ¿Hay un orden de operaciones documentado donde pueda saber cuándo sucederán ciertas cosas? ¿Es específico para un motor de Base de datos particular o parte del estándar SQL? Si decidiera incluir algún predicado en mi tabla de NOMBRES para filtrar los nombres cortos, (como len (NAME)> 3), ¿SQL Server también podría elegir aplicar eso después de intentar aplicar la subcadena? Si es así, parece que la única forma segura de hacer una subcadena sería envolverla en un constructo "case when" en el select?
Sí. 'CASE' es la única forma segura de hacerlo. Consulte http://stackoverflow.com/questions/5191701/tsql-divide-by-zero-encountered-despite-no-columns-containing-0/5203211#5203211 para obtener una buena respuesta sobre este tema. –
@Martin gracias por el enlace. No pude encontrar la manera de buscar preguntas similares a esta, ya que es algo abstracto. –