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 WHERE, 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 WHERE. 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, COUNT(PEDIDO.IMPORTE) TOTAL_PEDIDOS FROM CLIENTE LEFT OUTER JOIN PEDIDO ON (CLIENTE.DNI = PEDIDO.DNI) GROUP BY CLIENTE.APELLIDOS HAVING ( (COUNT(*) > 1) ) ORDER BY CLIENTE.APELLIDOS; APELLIDOS -------------------PEREZ GARCIA SEBASTIAN YUSTE TOTAL_PEDIDOS --------------3 2 Otra forma de realizar consultas dentro de consultas es por medio de un SELECT dentro de otro. En las cláusulas WHERE 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 * FROM CLIENTE WHERE EDAD > (SELECT EDAD FROM CLIENTE WHERE APELLIDOS='SEBASTIAN YUSTE'); DNI ---------87882215 57374811 42611580 APELLIDOS -------------------JIMENO DIAZ JIMENO ZOLA ROMERO ALONSO NOMBRE -------MIGUEL DANIELA LUIS EDAD -----61 61 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 WHERE, 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 * FROM CLIENTE WHERE NOT EXISTS (SELECT PEDIDO.DNI FROM PEDIDO WHERE CLIENTE.DNI = PEDIDO.DNI); DNI ---------22344556 57374811 APELLIDOS -------------------PEREZ LOPEZ JIMENO ZOLA NOMBRE -------ANA DANIELA EDAD -----30 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 FROM CLIENTE WHERE ( (CLIENTE.DNI = 12345678) ) UNION SELECT CLIENTE.DNI, CLIENTE.APELLIDOS, CLIENTE.NOMBRE FROM CLIENTE WHERE ( (CLIENTE.DNI = 22344556) ) ORDER BY 2,1; CLIENTE.DNI -----------12345678 22344556 CLIENTE.APELLIDOS -------------------PEREZ GARCIA PEREZ LOPEZ CLIENTE.NOMBRE --------------JOSE MARIA 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 FROM CLIENTE WHERE ( (CLIENTE.EDAD > 30) ) INTERSECT SELECT CLIENTE.APELLIDOS, CLIENTE.NOMBRE, CLIENTE.EDAD FROM CLIENTE WHERE ( (CLIENTE.EDAD > 60) ); CLIENTE.APELLIDOS -------------------JIMENO DIAZ JIMENO ZOLA ROMERO ALONSO CLIENTE.NOMBRE --------------MIGUEL DANIELA LUIS CLIENTE.EDAD ------------61 61 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