Unidad 6. Las subconsultas (I)


6.1. Introducción

Una subconsulta es una consulta que aparece dentro de otra consulta o subconsultas, en la lista de selección o en la cláusula WHERE o HAVING, originalmente no se podían incluir en la lista de selección.
Una subconsulta se denomina también consulta o selección interna, mientras que la instrucción que contiene la subconsulta es conocida como consulta o selección externa.

Aparece siempre encerrada entre paréntesis y tiene la misma sintaxis que una sentencia SELECT normal con alguna limitación:
No puede incluir una cláusula COMPUTE o FOR BROWSE y sólo puede incluir una cláusula ORDER BY cuando se especifica también una cláusula TOP.

Una subconsulta puede anidarse en la cláusula WHERE o HAVING de una instrucción externa SELECT, INSERT, UPDATE o DELETE, o bien en otra subconsulta. Se puede disponer de hasta 32 niveles de anidamiento, aunque el límite varía dependiendo de la memoria disponible y de la complejidad del resto de las expresiones de la consulta. Hay que tener en cuenta que para cada fila de la consulta externa, se calcula la subconsulta, si anidamos varias consultas, el número de veces que se ejecutarán las subconsultas ¡puede dispararse!

Cuando la subconsulta aparece en la lista de selección de otra consulta, deberá devolver un solo valor, de lo contrario provocará un error.

Ejemplo de subconsulta: Listar los empleados cuya cuota no supere el importe vendido por el empleado.

SELECT nombre

	FROM empleados

	WHERE cuota <= (SELECT SUM(importe)

					FROM pedidos

					WHERE rep = numemp);

Por cada fila de la tabla de empleados (de la consulta externa) se calcula la subconsulta y se evalúa la condición, por lo que utilizar una subconsulta puede en algunos casos ‘ralentizar’ la consulta, en contrapartida se necesita menos memoria que una composición de tablas.
Muchas de las instrucciones Transact-SQL que incluyen subconsultas se pueden formular también utilizando composiciones de tablas. Otras preguntas se pueden formular sólo con subconsultas.
En Transact-SQL, normalmente no hay una regla fija en cuanto a diferencias de rendimiento entre una instrucción que incluya una subconsulta y una versión semánticamente equivalente que no la incluya.
Podremos utilizar una subconsulta siempre y cuando no se quiera que aparezcan en el resultado columnas de la subconsulta ya que si una tabla aparece en la subconsulta y no en la consulta externa, las columnas de esa tabla no se pueden incluir en la salida (la lista de selección de la consulta externa).
 
Tenemos tres tipos de subconsultas:

  • Las que devuelven un solo valor, aparecen en la lista de selección de la consulta externa o con un operador de comparación sin modificar.
  • Las que generan una columna de valores, aparecen con el operador IN o con un  operador de comparación modificado con  ANY, SOME o ALL.
  • Las que pueden generar cualquier número de columnas y filas, son utilizadas en pruebas de existencia especificadas con EXISTS.

A lo largo del tema las estudiaremos todas.

Antes de terminar con la introducción queda comentar el concepto de referencia externa muy útil en las subconsultas.
A menudo, es necesario, dentro del cuerpo de una subconsulta, hacer referencia al valor de una columna en la fila actual de la consulta externa, el nombre de columna de la consulta externa dentro de la subconsulta recibe el nombre de referencia externa, ya que hace referencia a una columna externa.
En el ejemplo anterior numemp es una referencia externa, no es una columna del origen de datos de la subconsulta (pedidos), es una columna del origen de la consulta externa (empleados).
Hay que tener en cuenta de cómo se ejecuta la consulta; por cada fila de la consulta externa se calcula el resultado de la subconsulta y se evalúa la comparación.
En el ejemplo, se coge el primer empleado (numemp= 101, por ejemplo) y se calcula la subconsulta sustituyendo numemp por el valor 101, se calcula la suma de los pedidos del rep = 101, y el resultado se compara con la cuota de ese empleado, y así se repite el proceso con todas las filas de empleados.

El nombre de una columna dentro de la subconsulta se presupone del origen de datos de la subconsulta y, sólo si no se encuentra en ese origen, la considera como columna externa y la busca en el origen de la consulta externa.
Por ejemplo:


SELECT oficina, ciudad

FROM oficinas

WHERE objetivo > (SELECT SUM(ventas)

             FROM empleados

     		WHERE oficina = oficina); 

 La columna oficina se encuentra en los dos orígenes (oficinas y empleados) pero esta consulta no dará error (no se nos pedirá cualificar los nombres como pasaría en una composición de tablas), dentro de la subconsulta se considera oficina el campo de la tabla empleados. Con lo que compararía la oficina del empleado con la misma oficina del empleado y eso no es lo que queremos, queremos comparar la oficina del empleado con la oficina de oficinas, lo escribiremos pues así para forzar a que busque la columna en la tabla oficinas.


SELECT oficina, ciudad

FROM oficinas

WHERE objetivo > (SELECT SUM(ventas)

             FROM empleados

     		WHERE oficina = oficinas.oficina); 
Febrero-2010
Pág. 6.1

Atrás  Inicio  Adelante



.