Beruflich Dokumente
Kultur Dokumente
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:
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.
FROM empleados;
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)
COS (Coseno)
EXP (Exponente)
LN (Logaritmo Neperiano)
4
ROUND (number) (Redondeo Numérico)
SIGN (Signo)
SIN (Seno)
TAN (Tangente)
Y otras más…
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:
Y otras mas…
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
Ejemplo:
Estudiante s
7
4512 Suárez SOF
“GROUP BY columna” separa las filas del conjunto, en grupos de filas que
tienen el mismo valor en la columna
Estudiante s
La consulta:
SELECT
carrera,
count(*)
FROM
estudiantes
GROUP BY carrera;
Carrera COUNT(*)
8
---------- ---------------
SIS 2
SOF 3
ABO 3
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
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
Tomó la nota máxima de cada material (7, 9, 10, 4) y a estas las promedió
(30/4)= 7,5
COUNT (conteo)
MAX (máximo)
MIN (mínimo)
SUM (suma)
VARIANCE (varianza)
La cláusula FROM
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
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.
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
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:
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
join_con
dition:
ON
conditio
nal_expr
| USING (column_list)
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.
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 NOT sal > 1000 … NO es verdad que el salario de la fila es mayor a
1000”
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)
15
Los operadores de comparación son:
= igual
> 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
NOT BETWEEN límite inferior AND límite superior está fuera de un rango
inclusivo
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.
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.
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:
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:
SELECT empno, ename, job, mgr, hiredate, sal, comm, deptno, current_date
FROM empleados
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:
18
col_name2=expr2 ...] [WHERE
where_condition]
[ORDER BY ...]
[LIMIT row_count]
Ejemplo:
UPDATE empleados
UPDATE 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
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.
La consulta es:
21
SELECT ename, sal, (SELECT avg(sal) from empleados) promedio
FROM empleados;
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.
SELECT AVG(sal)
FROM empleados;
Ahora hay que comparar todos los salarios contra este valor, ahora conocido
y constante.
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:
Figura 4. Vemos que todos los empleados que ganan mas que el promedio
de sueldos
24
Vemos en la Figura 5, la ejecución de esta consulta con varias subconsultas:
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.
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.
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
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.
30
Si los promedios por trabajo son (valores al azar):
ANALYST, 1800
PRESIDENT, 5000
CLERK, 1200
PRESIDENT, 5000
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
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
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
34
Figura 15. Uso complejo de subconsultas en el UPDATE
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
36