TEMA 25: SUBCONSULTAS OBJETIVOS Ser capaces de realizar una consulta dentro de otra 1.- SUBCONSULTAS A veces interesa obtener dentro de una selección de datos, otra, esto se conoce como subconsulta. La subconsulta se hace a través de la cláusula HAVING, la cual trabaja de forma muy parecida a la cláusula, y se utiliza para considerar sólo aquellos grupos que satisfagan la cualificación dada en la misma. Las expresiones permitidas en la cláusula HAVING deben involucrar funciones agregadas. Cada expresión que utilice sólo atributos planos deberá recogerse en la cláusula. Por otro lado, toda expresión que involucre funciones agregadas debe aparecer en la cláusula HAVING. Si queremos solamente los clientes que han realizado más de un pedido se utilizará la consulta: SELECT CLIENTE.APELLIDOS, COUNTPEDIDO.IMPORTE TOTAL_PEDIDOS LEFT OUTER JOIN PEDIDO ON CLIENTE.DNI = PEDIDO.DNI GROUP BY CLIENTE.APELLIDOS HAVING COUNT* > 1 ORDER BY CLIENTE.APELLIDOS; APELLIDOS TOTAL_PEDIDOS -------------------- --------------- PEREZ GARCIA 3 SEBASTIAN YUSTE 2
Otra forma de realizar consultas dentro de consultas es por medio de un SELECT dentro de otro. En las cláusulas y HAVING se permite el uso de subconsultas subselects en cualquier lugar donde se espere un valor. En este caso, el valor debe derivar de la evaluación previa de la subconsulta. El uso de subconsultas amplía el poder expresivo de SQL. Si queremos conocer los clientes que tienen más edad que MARIA SEBASTIAN YUSTE 55 años utilizaremos la consulta: SELECT * EDAD > SELECT EDAD APELLIDOS='SEBASTIAN YUSTE'; DNI APELLIDOS NOMBRE EDAD ---------- -------------------- -------- ------ 87882215 JIMENO DIAZ MIGUEL 61 57374811 JIMENO ZOLA DANIELA 61 42611580 ROMERO ALONSO LUIS 68 Cuando revisamos la consulta anterior, podemos ver la palabra clave SELECT dos veces. La primera al principio de la consulta - a la que nos referiremos como la SELECT externa - y la segunda en la cláusula, donde empieza una consulta anidada - nos referiremos a ella como la SELECT interna. Para cada tupla de la SELECT externa, la SELECT interna deberá ser evaluada. Tras cada evaluación, conoceremos la edad de la tupla llamada 'APELLIDOS', y podremos chequear si la edad de la tupla actual es mayor. Si queremos conocer todos los clientes que no han realizado ningún pedido por ejemplo, para poderlos eliminar de la base de datos, utilizaremos:
SELECT * NOT EXISTS SELECT PEDIDO.DNI FROM PEDIDO CLIENTE.DNI = PEDIDO.DNI; DNI APELLIDOS NOMBRE EDAD ---------- -------------------- -------- ------ 22344556 PEREZ LOPEZ ANA 30 57374811 JIMENO ZOLA DANIELA 61 Como hemos descrito antes, la subconsulta se evalúa para cada tupla de la consulta externa. Combinación de Resultados : UNION, INTERSECT Estas operaciones calculan la unión y la intersección del conjunto de tuplas obtenidas en dos ó más subconsultas. La siguiente consulta es un ejemplo de UNION: SELECT CLIENTE.DNI, CLIENTE.APELLIDOS, CLIENTE.NOMBRE CLIENTE.DNI = 12345678 UNION SELECT CLIENTE.DNI, CLIENTE.APELLIDOS, CLIENTE.NOMBRE CLIENTE.DNI = 22344556 ORDER BY 2,1; CLIENTE.DNI CLIENTE.APELLIDOS CLIENTE.NOMBRE ------------ -------------------- --------------- 12345678 PEREZ GARCIA JOSE MARIA 22344556 PEREZ LOPEZ ANA
Nótese que en la ordenación esta vez no se pone el nombre de las columnas, sólo el número de orden de las columnas primero ordena por Apellidos y luego por DNI. De igual modo que la sentencia UNION hace una suma de datos O lógico, con la sentencia INTERSECT se muestra el Y lógico de dos ó más tablas Pueden hacer referencia a la misma. Aquí tenemos un ejemplo para INTERSECT: SELECT CLIENTE.APELLIDOS, CLIENTE.NOMBRE, CLIENTE.EDAD CLIENTE.EDAD > 30 INTERSECT SELECT CLIENTE.APELLIDOS, CLIENTE.NOMBRE, CLIENTE.EDAD CLIENTE.EDAD > 60 ; CLIENTE.APELLIDOS CLIENTE.NOMBRE CLIENTE.EDAD -------------------- --------------- ------------- JIMENO DIAZ MIGUEL 61 JIMENO ZOLA DANIELA 61 ROMERO ALONSO LUIS 68 La sentencia INTERSECT no está contemplada en todos los motores de bases de datos. RESUMEN DEL TEMA 25 Se ha visto como obtener datos a partir de consultas dentro de consultas, ello se puede hacer principalmente de dos maneras:
Si la consulta conlleva datos calculados de otra consulta, se utiliza la sentencia HAVING. Si la consulta es un subconjunto de otra consulta se utiliza SELECT dentro de otro SELECT. Cuando una consulta es una suma de consultas parciales se utiliza la sentencia UNION entre consultas