Sie sind auf Seite 1von 36

Consultas

básicas y
Subconsulta
s

Base de Datos I

1
Consultas Simples y sobre más
de una tabla.
Iniciaremos con SELECT la revisión de las sentencias del lenguaje de
manipulación de datos, conocido por sus siglas en inglés DML por Data
Management Language.

Sentencia SELECT
La sentencia SELECT permite consultar los datos que están en las tablas y en
las vistas. Habitualmente se usa llamar consultas a una sentencia SELECT. Sus
cláusulas son:

SELECT <lista de columnas, valores constantes, funciones, subconsultas,


etc.>

FROM <lista de tablas, vistas, subconsultas>

WHERE <condición> [AND, OR, NOT] <condición>

GROUP BY <lista de columnas>

HAVING <condición> [AND, OR, NOT] <condición>

ORDER BY <lista de columnas, numero de orden o alias de columna> [DESC,


ASC];

Las cláusulas obligatorias son SELECT y FROM en Oracle y en otras bases


como MySQL sólo es obligatorio la cláusula SELECT.

En esta cláusula se puede realizar la operación Project del Algebra relacional,


cuando enumeramos sólo algunas columnas de la tabla a consultar. Para
evitar esta operación, pueden incluirse todas las columnas, una a una o usar
el operador asterisco (‘ * ‘) que indica que deben traerse todos las columnas
de la o las tabla/s del FROM.

En la primera cláusula podemos combinar columnas de las tablas, vistas o


subconsultas de la cláusula FROM, funciones como las que veremos en los

2
párrafos siguientes y subconsultas. Estas subconsultas deben devolver un
solo valor, por lo que se llaman Escalares. También podemos agregar valores
literales que se repetirán por cada fila mostrada. Veamos un ejemplo (el
resultado en la figura 1) la sentencia muestra datos constantes, una columna
con el nombre de los empleados, luego el sueldo y en la columna aumento
el calculo de sueldo con un 20% de aumento. Es para destacar que en los dos
últimos se usó un “Alias de Columna” que son usados para titular las
columnas con un nombre distinto al de las columnas de la tabla.

SELECT ‘El nombre es:’, ename, salario salarioAnterior, salario*1.20


aumento,

FROM empleados;

Figura 1: Resultado de SELECT en MySQL Query Browser

Funciones de fila simple


En el ejemplo anterior vimos el uso de una función de fila simple, el operador
multiplicación ‘*’.

Las funciones de fila simple retornan un solo valor por cada fila de una tabla
o vista consultada. Estas funciones pueden usarse en la lista de columnas del
SELECT, en las cláusulas WHERE y HAVING y demás.

3
Funciones Numéricas
Las funciones numéricas que reciben y devuelven valores numéricos, la
mayoría de las funciones que retornan valores NUMBER con exactitud en 38
dígitos decimales.

Las mas simples son operadores matemáticos ‘*’ por, ‘/’ dividido, ’+’ mas, ’-
‘ menos

Las funciones como COS, COSH, EXP, LN, LOG, SIN, SINH, SQRT, TAN y TANH
tienen una exactitud de 36 de dígitos decimales y las funciones ACOS, ASIN,
ATAN y tienen una exactitud de 30 dígitos decimales. Algunas funciones del
SQL de ORACLE 10g de ejemplo:

ABS
(Valor
Absoluto)
ACOS
(Arc
Coseno)

ASIN (Arc Seno)

ATAN (Arc Tangente)

CEIL (Valor tope)

COS (Coseno)

COSH (Coseno Hiperbólico)

EXP (Exponente)

FLOOR (Valor Mínimo)

LN (Logaritmo Neperiano)

LOG (Logaritmo Decimal)

MOD (Resto de la división)

POWER (elevar a una potencia)

4
ROUND (number) (Redondeo Numérico)

SIGN (Signo)

SIN (Seno)

SINH (Seno Hiperbólico)

SQRT (Raíz Cuadrada)

TAN (Tangente)

TANH (Tangente Hiperbólico)

TRUNC (number) (Truncar Numérico)

Y otras más…

Las funciones de carácter que devuelven valores caracteres son:

CHR (devuelve un carácter de acuerdo a un argumento)

CONCAT (concatena valores)

INITCAP (pone mayúscula a las primeras letras de cada palabra)

LOWER (transforma en minúsculas)

LPAD (completa a la izquierda con un carácter hasta una cantidad de


caracteres)

LTRIM (recorta una cantidad de caracteres a la izquierda)

REPLACE (reemplaza un carácter por otro)

RPAD (completa a la derecha con un carácter hasta una cantidad de


caracteres)

RTRIM (recorta una cantidad de caracteres a la derecha)

SUBSTR (toma una sub cadena de una cantidad de caracteres desde una
posición determinada) UPPER (transforma en mayúsculas)

Y otras mas…

5
Las funciones de fecha y hora son:

ADD_MONTHS (suma meses a una fecha)

CURRENT_DATE (la fecha del sistema)

EXTRACT (datetime) (extrae fecha u hora)

LAST_DAY (ultimo día del mes de la fecha argumento)

MONTHS_BETWEEN (cantidad de meses entre dos fechas argumento)

ROUND (date) (redondeo de fechas, a mes o a año)

SYSDATE (fecha del sistema)

TO_CHAR (datetime) (traducir a caracteres una fecha)

TRUNC (date) (truncar una fecha)

Y otras mas…

Funciones generales de comparación


Las funciones generales de comparación determina los valores mayores o
menores de un conjunto de datos:

GREATEST (mayor)

LEAST (menor)

Funciones de Conversión
Convierten un valor de un tipo de datos (ver más adelante en esta lectura) a
otro tipo de datos:

TO_CHAR (character)

TO_CHAR (datetime)

TO_CHAR (number)

6
TO_CLOB

TO_DATE

TO_LOB

TO_MULTI_BYTE

TO_NUMBER

Funciones de Grupo

Las funciones de grupo devuelven un solo resultado basado en grupos de


filas, en vez de filas únicas, considerando que el conjunto de filas pueda
tener una sola fila. Las funciones de grupo pueden aparecer en Lista de
columnas en el SELECT y en las condiciones dentro de la cláusula HAVING,
pero es un error común incluirlas en la cláusula WHERE, lo que retorna un
error de ejecución.

Las funciones de grupo son usadas comúnmente en combinación con la


cláusula GROUP BY, con la que se divide a las filas seleccionadas porque
cumplen con las condiciones de filtro del WHERE, en grupos basados en los
distintos valores de las columnas incluidas en el GROUP BY.

Ejemplo:

Dada la tabla de Estudiantes

Estudiante s

Legajo Apellido Carrera


7898 Messi SIS
6677 García SIS
6644 Bremen SOF
2123 López ABO
5522 Palermo SOF
2123 López ABO
5221 Vianni ABO

7
4512 Suárez SOF

Tabla 1: Tabla Estudiantes

“GROUP BY columna” separa las filas del conjunto, en grupos de filas que
tienen el mismo valor en la columna

Estudiante s

Legajo Apellido Carrera


7898 Messi SIS
6677 García SIS

6644 Bremen SOF


5522 Palermo SOF
4512 Suárez SOF

3566 Perez ABO


2123 López ABO
5221 Vianni ABO

Tabla 2: Tabla Estudiantes agrupada por Carrera

La consulta:

SELECT
carrera,
count(*)
FROM
estudiantes

GROUP BY carrera;

Nos da como resultado:

Carrera COUNT(*)

8
---------- ---------------

SIS 2

SOF 3

ABO 3

En el ejemplo se aplicó la función COUNT(*) que cuenta las filas


seleccionadas y filtradas por la consulta y muestra el resultado del conteo.

Si se usa una función de grupo sin la cláusula GROUP BY estas se aplicarán a


todo el conjunto de filas seleccionadas. Se usan las funciones de grupo
también en la cláusula HAVING para filtrar los grupos que no cumplen las
condiciones. HAVING filtra filas mientras que WHERE filtra Filas, en un paso
previo a que se armen los grupos.

Todas las funciones de grupo ignoran los valores nulls, y COUNT cuanto
todas las filas tenga valores null en las columnas usadas en COUNT devuelve
0 (cero).

Es posible anidar funciones de grupo, dada la tabla NOTAS (se muestran solo
algunas columnas):

Notas

Legajo Id_Materia Nota


7898 1 7
6677 1 7
6644 2 8
2123 2 9
5522 3 10
2123 3 10
5221 5 2
4512 5 4

Tabla 3: Tabla Notas

9
Para calcular el promedio de la nota más alta de cada materia se puede
hacer:

SELECT AVG(MAX(nota))
FROM exámenes

GROUP BY id_materia;

AVG(MAX(nota))

-----------7,5

Esta consulta evalúa el agrupamiento interno (MAX(nota)) trayendo las


notas mas altas de cada materia, las agrupa nuevamente y luego calcula el
promedio de éstas.

Tomó la nota máxima de cada material (7, 9, 10, 4) y a estas las promedió
(30/4)= 7,5

Algunas de las funciones de grupo más usadas son:

AVG (Average o promedio)

COUNT (conteo)

MAX (máximo)

MIN (mínimo)

STDDEV (desviación estándar)

SUM (suma)

VARIANCE (varianza)

La cláusula FROM

En la cláusula FROM se enumeran las tablas, vistas y subconsultas que deben


ser seleccionadas para buscar las columnas que se enumeran en el SELECT.

10
Cuando hay más de una referencia a tablas, estamos hablando de que la
consulta es MULTITABLA. En este caso estamos en frente de la aplicación de
la operación Reunión (JOIN) del algebra relacional y si no escribimos
condiciones de reunión en el WHERE, el optimizador de consultas realizará
un Producto Cartesiano relacionando todas las filas de las tablas reunidas, lo
que genera resultados falsos, si tuviéramos 5 alumnos y 3 exámenes
rendidos, la reunión sin condiciones de reunión, nos daría 15 filas (5X3 filas).
Esto produce un gran volumen de reuniones que habitualmente no tienen
uso, un uso que he observado de esta operación, Producto Cartesiano, es
que un caso que quiera relacionar todos los jugadores de un torneo de tenis,
para armar los partidos posibles, teniendo en cuenta que debo eliminar los
pares en los que se repiten los mismos jugadores. ¿Cómo sería esto?
Supongamos que tenemos 6 jugadores (‘A’, ’B’, ’C’, ’D’, ’E’, ’F’) y queremos
tener listos todos los partidos posibles, (imposibles serían ‘A’ contra ‘A’)
puedo hacer el Producto Cartesiano de todos elementos

Primer intento dejó un Producto Cartesiano, unimos la tabla empleados:

SELECT l.ename Local, ‘ juega con ‘,


v.ename Visita FROM empleados l,
empleados v

Si esta tabla tiene 14 filas, da un resultado de 196 filas (ver en la figura 2) se


muestran apenas los primeros para brevedad.

En la siguiente consulta agregamos la consulta que resuelve el


requerimiento de armar los partidos de ajedrez en un campeonato interno
de la empresa (ver figura 3).

SELECT l.ename Local, ' juega con ', v.ename Visita

FROM empleados l, empleados v

WHERE l.ename <> v.ename

11
No nos adelantamos al próximo apartado, pero vemos que hay una cláusula
WHERE con una condición que evita unir el mismo empleado como local y
como visitante.

Es importante destacar que hemos usado Alias de Tablas para identificar las
columnas “ename”, que al venir de la misma tabla, pero repetida en el
FROM, hemos tenido que calificarla con la letra que escribimos a
continuación de la tabla en esta cláusula. Esta forma de nombrar las
columnas de una tabla en una posición determinada se llama Alias de tabla,
y como recomendación use la inicial del sentido que tiene cada tabla en el
select, note que usamos “l” para Local y “v” para Visitante.

Figura 2. Producto cartesiano, vemos que SMITH juega con SMITH es un


partido imposible, pero creado por esta operación

12
Figura 3. Reunión sin Producto cartesiano, se agregó una restricción en el
WHERE y vemos que armó el conjunto de partidos posibles

Entonces, cuando en el FROM se unen tablas, para evitar el producto


cartesiano, se puede escribir una condición de reunión, generalmente en
estas consultas, se unen las tablas con claves foráneas y claves primarias,
concretando la reunión entre tablas relacionadas. Pero esto no es
excluyente, pueden escribirse condiciones de reunión con columnas del
mismo dominio de valores, es decir comparables…

Tenemos dos alternativas de sintaxis para reunir tablas, una es la que vimos,
la mas antigua, es decir nombrarlas en el FROM, y luego evitando el
producto cartesiano con condiciones de reunión en el WHERE. La segunda
es escribiendo la palabra JOIN entre las tablas y luego en el mismo FROM
escribir la condición dentro del operador ON, de esta manera, para obtener
el mismo resultado que la figura 3 anterior:

SELECT l.ename Local, ' juega con ', v.ename Visita

FROM empleados l JOIN empleados v ON (l.ename <> v.ename)

13
Esto es considerado parte como estándar desde SQL3 y adjunto la ayuda de
MySQL sobre la sintaxis de esta forma de escribir Reuniones

table_reference [INNER | CROSS] JOIN table_factor [join_condition]


| table_reference STRAIGHT_JOIN table_factor
| table_reference STRAIGHT_JOIN table_factor ON condition
| table_reference LEFT [OUTER] JOIN table_reference join_condition |
table_reference NATURAL [LEFT [OUTER]] JOIN table_factor
| table_reference RIGHT [OUTER] JOIN table_reference join_condition
| table_reference NATURAL [RIGHT [OUTER]] JOIN table_factor

join_con
dition:
ON
conditio
nal_expr
| USING (column_list)

En la sintaxis aparecen operadores que no serán motivo de estudio en esta


materia pero que pueden ser consultados para ampliar el tema en
Wikipedia.

La cláusula WHERE
En esta cláusula se escriben condiciones de filtro que permiten elegir
aquellas filas que nos interesa mostrar. La condición es una construcción que
tiene tres partes en general y como excepción cuando se usa el operador de
comparación EXISTS o NOT EXISTS, en cuyo caso que tiene dos partes.

Una condición tiene como elementos una columna, un operador de


comparación y un valor constante, otra columna, una variable o una
subconsulta que devuelva uno o varios valores, siendo aceptado los varios
valores solamente si el operador es IN, NOT IN, EXISTS y NOT EXISTS que
tratan con lista de valores.

Ejemplos de condiciones: “Una fila es elegida si…

14
WHERE sal > 1000 … es verdad que el salario de la fila es mayor a
1000”

WHERE ename = ‘SMITH’ …es verdad que el apellido de la fila es ‘SMITH’ (en
mayúsculas)”

WHERE hiredate < ‘01/03/1998’… es verdad que la fecha de contratación es


anterior al primero de marzo de 1998”

o negarlas con NOT,

“Una fila es elegida si…

WHERE NOT sal > 1000 … NO es verdad que el salario de la fila es mayor a
1000”

También pueden combinarse condiciones, lo que permiten evaluar


simultáneamente varias condiciones con los coordinadores ‘AND’ y ‘OR’ con
lo que podemos tener que:

“Una fila es elegida si …

WHERE (sal > 1000) AND (ename = ‘SMITH’) … es verdad que el salario
de la fila es mayor a 1000 Y la misma fila tiene un valor en apellido igual a
‘SMITH’ (en mayúsculas)

WHERE hiredate < ‘01/03/1998’ OR (ename = ‘SMITH’ ) … es verdad que la


fecha de contratación es anterior al primero de marzo de ese año o su
columna es igual a ‘SMITH’ (en mayúsculas)”

Las cantidad de combinaciones no tiene limites en una cláusula WHERE y es


una de las competencias mas usadas la de entender esta cláusula y escribir
condiciones que permitan encontrar todas las filas que deben ser
encontradas para cumplir con una tarea.

15
Los operadores de comparación son:

= igual

< menor que

> mayor que

<> distinto que

= ANY/ALL compara con todos los valores de una lista, =ANY


es equivalente a IN < ALL es menor que todos los valores de
una lista o subconsulta

> ALL es mayor que todos los valores de una lista o subconsulta

< ANY es menor que algunos de los valores de una lista o subconsulta

> ANY es mayor que algunos de los valores de una lista o subconsulta

IN es igual que al menos uno de los valores de una lista o subconsulta

NOT IN No es igual que al menos uno de los valores de una lista o


subconsulta

BETWEEN límite inferior AND límite superior está dentro de un rango


inclusivo

NOT BETWEEN límite inferior AND límite superior está fuera de un rango
inclusivo

LIKE patrón como % (comodines de múltiples valores y múltiple cantidad) y


_ Idem pero sólo de una posición.

NOT LIKE no cumple con un patrón como % (comodines de múltiples valores


y múltiple cantidad) y _ Idem pero sólo de una posición.

EXISTS test de existencia en una subconsulta

NOT EXISTS test de No existencia en una subconsulta

En el próximo módulo de la materia se practicarán estos operadores de


comparación.

16
La cláusula GROUP BY
Como vimos en la explicación de las funciones de grupo, esta cláusula define
sobre en qué valores de columna o columnas se basará el optimizador para
agrupar las filas por sus distintos valores.

La cláusula HAVING
Una vez definidos los grupos, se puede escribir en HAVING una condición
usando funciones de grupo para poder filtrar o seleccionar y mostrar solo
aquellos grupos que cumplen con las condiciones presentes de HAVING.

Se la suele comparar con la cláusula WHERE, por que aplica condiciones,


pero que quede claro que WHERE filtra filas y HAVING filtra grupos armados
en GROUP BY.

La cláusula ORDER BY
La última cláusula de la sentencia SELECT es la que permite darle el orden
deseado a las filas encontradas que cumplan la condición, junto con valores
de funciones y otros cálculos o formateos realizados con esta sentencia. Es
posible combinar varias columnas para ordenar y el orden de aparición de
estas columnas en la cláusula ORDER BY no es trivial, comenzará a ordenar
por la primera columna que aparece luego de la palabra BY.

Existen dos indicadores del sentido en el cual se debe ordenar, DESC de


descendiente o ASC, de ascendente. Si no se indica ninguno toma por
defecto ASC.

De este modo, si usamos DESC como indicador del sentido del


ordenamiento, mostrará de mayor a menor y si es ASC, mostrará de menor
a mayor.

Sentencias DML, Transacciones, Confirmación y Deshacer.

Sentencia INSERT

17
La primer sentencia del grupo de sentencias del Data Management Language
es INSERT, que permite insertar filas en una tabla, permitiendo ingresar
columna a columna los valores de cada una de ellas:

INSERT INTO empleados (empno, ename, job, mgr, hiredate, sal,


comm, deptno) VALUES (8000, ‘Alves, Pedro’, ‘Programa’, 7411,
3500, null, 20)

La lista de columnas se puede obviar, pero por claridad se sugiere no dejar


de consignarla.

Otra forma para insertar filas en una tabla, y más de una por ejecución
presentamos esta sintaxis, que incluye un select dentro del Insert, llamando
habitualmente a esta sentencia subordinada Subconsultas:

INSERT INTO empleados_histórico (empno, ename, job, mgr, hiredate, sal,


comm, deptno, fecha_carga)

SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno, current_date

FROM empleados

WHERE hiredate < ‘01/01/2000’;

En este caso hacemos el supuesto de que estamos insertando en la tabla de


empleados históricos, los empleados que hayan sido contratados antes del
primero de enero del año 2000, agregando la fecha actual en la columna
“fecha_carga” de la tabla histórica. En esta sola operación se insertaran mas
de una fila en la tabla objetivo y es una de las aplicaciones de las
subconsultas que veremos mas en detalles en las siguientes lecturas.

Sentencia UPDATE
La sentencia para cambiar el valor de una o más columnas en una tabla es
UPDATE que tiene la siguiente sintaxis en MySQL, aumentando el sueldo de
todos los empleados de la tabla:

UPDATE [LOW_PRIORITY] [IGNORE]


tbl_name SET col_name1=expr1 [,

18
col_name2=expr2 ...] [WHERE
where_condition]
[ORDER BY ...]
[LIMIT row_count]

Ejemplo:

UPDATE empleados

SET sal = sal * 1.2;

Esto provoca un aumento de sueldo de un 20% a todos los integrantes de la


empresa, si se deseara que se le aumente a unos pocos, se puede usar la
cláusula WHERE, que tiene las mismas características que tiene en la
sentencia SELECT. Si, por ejemplo, sólo nos interesa aumentarle el sueldo a
los que ganan entre 1000 y 1200, la sintaxis sería esta:

En esta sentencia UPDATE se pueden usar subconsultas como argumento del


SET y como parte del WHERE como en cualquier sentencia SELECT.

UPDATE empleados

SET sal = (SELECT AVG(sal) FROM empleados)

WHERE sal BETWEEN 1000 AND 1200;

En la sentencia anterior, se ha modificado el sueldo de los que ganan entre


1000 y 1200, por el valor del sueldo promedio de todos los empleados.

Sentencia MERGE
La sentencia MERGE es una combinación de INSERT y UPDATE, y con la
sintaxis que contiene las dos sentencias, al ejecutarse busca la fila, si la
encuentra la modifica de acuerdo a la sintaxis del UPDATE y si no existe
ninguna fila que cumpla con el criterio del WHERE, la inserta con la sintaxis
del INSERT, y si una fila cumple con una condición la puede borrar.

19
Ejemplo de la sintaxis en ORACLE 10g:

Sentencia DELETE
Para borrar filas de una tabla, la sentencia DELETE es muy simple alcanza
completar con el nombre de la tabla y opcionalmente puede incorporarse la
cláusula WHERE con el funcionamiento visto en la sentencia SELECT.

DELETE emp1

WHERE sal > 5000;

Sin la cláusula WHERE y su condición borraría todas las filas de la tabla, en


cambio con esa cláusula, borrará aquellas filas con valores mayores a 5000
en la columna sal.

SQL A MAYOR PROFUNDIDAD

En el Módulo anterior se introdujeron las sentencias del Lenguaje SQL que


permiten desarrollar todas las tareas que una aplicación debe realizar,
cargar filas, actualizarlas, eliminarlas y consultarlas para brindar información
al usuario final.

20
Para profundizar en el uso de todas las características de la sentencia
SELECT, es que en esta lectura veremos la posibilidad que ofrece el lenguaje
de poder anidar consultas SELECT, llamadas Subconsultas, en otra consulta
SELECT y en las sentencias INSERT, UPDATE, DELETE y CREATE TABLE.

Subconsultas en el SELECT
En la sentencia SELECT se pueden incluir subconsultas, en la cláusula SELECT
para traer un valor que devolverá por cada fila recuperada por la consulta
contenedora de la sub consulta, que llamaremos principal. Esto hace que la
sub consulta obligatoriamente deba devolver sólo un valor.

En el ejemplo de la Figura 1, vemos un ejemplo de una subconsultas que


para cada fila devuelve el valor de promedio de sueldos sobre la misma
tabla. Son dos accesos a la misma tabla, el de la subconsultas, que se realiza
por cada fila encontrada por la consulta principal:

Figura 1. Ejecución de una subconsultas dentro de la lista de columnas del


SELECT

La consulta es:

21
SELECT ename, sal, (SELECT avg(sal) from empleados) promedio

FROM empleados;

Es interesante el uso de estas subconsultas que se denominan subconsultas


escalares y recuerdan el uso de las funciones de fila simple, por que devuelve
un valor (y sólo uno) para cada fila procesada en la consulta principal. Notar
el uso de alias de columna “promedio” que evita que la columna se titule
“(SELECT … )” .

Otro uso de subconsultas en la sentencias SELECT es en la cláusula FROM,


allí toman el nombre de ‘In line views’ por que cumplen la función de ser
como vistas, sin necesidad de crearlas como objetos de esquema. En la figura
2 vemos un ejemplo de subconsultas en el FROM.

Figura 2. Una subconsultas en el FROM de la consulta principal

Esta forma de escribir subconsultas, permite al desarrollador tener el poder


de las vistas sin necesidad de tener que crearlas en el esquema, solo se
escriben y se ejecutan.

22
El uso de subconsultas en el WHERE, se justifica en la necesidad de realizar
filtros con valores que ya están almacenados en las tablas de la base.

El caso de ejemplo deriva de un requerimiento muy simple del usuario: “Es


necesario saber qué empleado gana más sueldo que el sueldo promedio de
toda la empresa” y sabemos que el promedio del sueldo se obtiene con esta
consulta:

SELECT AVG(sal)
FROM empleados;

Vemos el resultado de la consulta, en la Figura 3.

Figura 3 resultado del promedio de sueldos de todos los empleados

Ahora hay que comparar todos los salarios contra este valor, ahora conocido
y constante.

Podría hacer simplemente:

23
Pero si hay aumento de salarios o ingresan nuevos empleados, el promedio
será distinto del calculado, por lo que se prefiere hacer una sub consulta y
obtener el promedio en el momento de realizar la ejecución de la consulta
principal:

En vez de la constante colocamos la sentencia con la que obtenemos el valor


de la constante y vemos el resultado:

Figura 4. Vemos que todos los empleados que ganan mas que el promedio
de sueldos

Si recordamos el valor obtenido en la consulta ‘interna’, era


aproximadamente 2073, por lo que comprobamos que funcionó, ahora nos
despreocupamos de calcularlo a mano antes, la subconsultas lo hará por
nosotros. Si reunimos los dos usos en el SELECT y en el FROM de
Subconsultas, podríamos saber ahora cuanto gana de más cada empleado:

24
Vemos en la Figura 5, la ejecución de esta consulta con varias subconsultas:

Figura 5. Ejecución de la Consulta con tres subconsultas con diferentes usos

Siguiendo con el uso de subconsultas en el WHERE, resta mencionar que es


importante elegir adecuadamente el operador de comparación por que si
definimos que es igual, mayor, menor que el valor que devuelve la sub
consulta, se ésta devolviera más de un valor, la consulta completa daría error
al momento de ejecutarse, con un mensaje que diría que la subconsultas que
va a ser comparada como un solo valor, ha devuelto mas valores de los
esperados.

Si por el contrario queremos usar el operador de comparación IN, NOT IN, o


los operadores >, =, < con los modificadores ALL o ANY, podremos comparar
un valor de una columna contra un conjunto o lista de valores.

25
Las subconsultas se pueden usar también en la cláusula ORDER BY, aunque
en casos aislados, por ejemplo para desordenar las filas en base a un valor
arbitrario. Veremos en la Figura 6, todas las filas ordenadas alfabéticamente
y en orden ascendente por apellido. Luego en la figura 7 desordenadas
aleatoriamente y en la Figura 8, repetimos para comprobar que trae otro
orden. Se usa la función RND() que genera números aleatorios en MySQL.

Figura 6 Consulta ordenada

26
Figura 7. Primer consulta desordenada

27
Figura 8. Segunda consulta desordenada, comparar con la Fig. 7

Entonces, este uso de una sub consulta con una función RND() en el ORDER
BY permitirá mezclar el orden de aparición de las filas de una consulta
común.

Sub consultas correlacionadas

Para estudiar este tipo de consultas sirve conocer para qué sirven y cómo
funcionan. El enunciado anterior, resuelto con consultas simples era “Traer
los apellidos de los empleados que ganan más que el promedio de los
sueldos de TODA la empresa”. Es claro entonces que el motor obtiene ese
valor y lo compara con todas las filas del la consulta principal.

En estas sub consultas simples, como las que resuelve esta consigna, el
optimizador de SQL empieza a ejecutar la sentencia principal y cuando
encuentra la sub consulta, la resuelve y obtiene el o los valores de las tablas
afectadas y mantiene este resultado en memoria hasta que termina el
proceso de la consulta principal. En las sub consultas correlacionadas el
proceso es diferente, cuando el optimizador intenta ejecutar la sub consulta
encuentra un Alias a una tabla de la consulta principal, cambia la estrategia
y lee la primer fila de la consulta principal, allí conoce el valor que esta
necesitando la subconsultas y, con esta información ejecuta la sub consulta,
obtiene el valor buscado, el promedio en este caso y recién ahí decide si la
fila actual de la consulta principal cumple con la condición, si lo hace es
seleccionado el empleado y si no, trae la siguiente fila y vuelve a realizar todo
el mismo proceso, aceptando o rechazando filas si cumplen o no la
condición. Este proceso, se habrá dado cuenta, repite tantas veces la
ejecución de la sub consulta, como filas encuentre la consulta principal. Este
proceso es evidentemente más costoso en tiempo que la sub consulta
simple, ya que la subconsultas se ejecuta una sola vez.

Entonces, si el requerimiento es que debo traer los que ganan más pero de
un subgrupo de filas, en el cual está incluido el empleado a elegir, es decir,
traer el empleado que gana más que el promedio de los empleados que
tienen su mismo trabajo, la solución anterior de sub consulta simple, ya no

28
se aplica. Es necesario que la sub consulta conozca un dato de la consulta
principal para traer el promedio correcto para comparar con la fila que esta
procesando la consulta principal. Este contacto entre niveles de ejecución se
denomina REFERENCIA EXTERNA, la sub consulta tiene una variable que se
inicializa en la consulta principal.

Esta sería la consulta que resuelve este requerimiento, note el uso de los
alias de tablas para realizar la REFERENCIA EXTERNA

SELECT ename, sal


FROM empleados E1
WHERE sal > (SELECT avg(sal)
FROM empleados E2
WHERE E2.job = E1.job);

E1 es una referencia externa en la sub consulta que trae el valor de la fila


que esta consultando la principal y ayuda a la resolución de la consulta

En la figura 9 agregamos la subconsultas correlacionada en el SELECT para


comprobar que los promedios son diferentes en cada trabajo diferente, que
es lo que se busca calcular con las REFERENCIAS EXTERNAS.

29
Figura 9. Subconsultas Correlacionadas

Consultas complejas

Bajo este título vamos a colocar las consultas que combinan cada uno de los
temas que hemos visto individualmente, para comprender el poder de las
sentencias SELECT del SQL, por último y cerrando esta lectura, veremos los
casos de UPDATE, DELETE e INSERT que combinan también lo visto para
SELECT.

Anidando funciones de grupo

Las funciones de grupo en algunos motores como ORACLE pero no en otros,


como en MySQL pueden usarse una dentro de otra, por ejemplo para
calcular el máximo de los promedios de sueldo de las funciones laborales.
Esta sería la consulta que lo resuelve:

30
Si los promedios por trabajo son (valores al azar):

ANALYST, 1800

PRESIDENT, 5000

CLERK, 1200

La sentencia propuesta elegirá

PRESIDENT, 5000

Al anidar las funciones de grupo es obligatorio que exista la cláusula GROUP


BY.

Funciones de grupo y multi tablas

Es tarea habitual tener que emitir una información de las tablas que
contemple datos agrupados de distintas tablas y la combinación de múltiples
tablas en una misma consulta, por ejemplo, el requerimiento de mostrar los
Departamento con su nombre y la cantidad de empleados y monto total de
sueldos que se pagan. En la Figura 10 vemos el primer intento de agrupar los
resultados. Observar el uso de las condiciones de reunión con los alias de
tabla e y d.

31
Figura 10. Agrupando por columnas de una tabla y calculando por columnas
de otras tablas

En el ejemplo agregamos un nivel más de agrupamiento, note que si


agregamos una columna sin función de grupo en el SELECT, debe ir al GROUP
BY. Lo podemos ver en la Figura 11. Aumentan las filas resultado y estas
definen más totales específicos.

Figura 11. Agregamos otro nivel de agrupamiento, Trabajo

Funciones de grupo y multitablas y subconsultas

32
A los ejemplos anteriores le agregamos más requerimientos, para observar
como crece en complejidad la consulta. Ahora nos piden que muestre
solamente las localidades cuya cantidad de empleados sea mayor a uno. Ver
Figura 12

Figura 12. Funciones de Grupos, Multi tablas, más sub consultas

EL resto de las Sentencias DML

En las sentencias del sub lenguaje DML, tenemos posibilidades de aplicar las
características del SELECT y sus cláusulas, por ejemplo, para sacar datos de
otras tablas con sub consultas y luego insertarlas en otras tablas como con
la sentencia INSERT. Usaremos la tabla emp1, que no tiene filas y las mismas
columnas de empleados y realizaremos un INSERT con algunas filas de la
tabla empleados, sólo los empleados del departamento 10. ACLARACIÓN:
Esta acción incorporará redundancia en el modelo, si fuera necesario
trabajar en forma específica con este conjunto de tablas, se puede usar una
Vista, tema no incluido en este trabajo. Veamos la sentencia INSERT con sub
consultas y su resultado en la Figura 13 y 14.

33
Figura 13 INSERT con subconsultas

Figura 14. Resultado del INSERT con sub consulta, todos los datos de los
empleados del departamento 10

Para UPDATE, podemos usar subconsultas para obtener un valor de las


tablas para modificar los valores de la columna y también usar la cláusula
WHERE con todo el potencial que tiene en el SELECT.

Mostraremos en la Figura 15 una sentencia UPDATE con sub consultas


simples y correlacionadas. Notar el uso de las REFERENCIAS EXTERNAS para
este último tipo de subconsultas.

34
Figura 15. Uso complejo de subconsultas en el UPDATE

Figura 16. Estado después del UPDATE complejo

Observamos que el salario de Clark se ha modificado y ahora tiene el


promedio general de la empresa.

Por último, nombraremos que con DELETE se puede utilizar una cláusula
WHERE como con UPDATE para limitar el alcance de actualización o borrado,
solamente a las filas que cumplen con las condiciones del filtro. Vale
destacar que, si no se incluye la cláusula WHERE en estas sentencias SQL, al
ejecutarse modifican o borraran TODAS las filas de la tabla afectada.

Con este último caso hemos cubierto los temas teóricos previstos en el
presente módulo.

35
Referencias Bibliográficas

[Lorentz, 2007] Oracle Database SQL Reference, 10g Rel 2 (10.2) Junio 2005

Disponible en http://tahiti.oracle.com

[Ora, 2009] Manual Oficial Oracle Concepts, disponible en linea


http://www.adpgmbh.ch/ora/concepts/transaction.html - visitado Ago
2009

36

Das könnte Ihnen auch gefallen