jueves, 8 de marzo de 2012

Introducción SQL (Comando SELECT 3ra parte)

Funciones Condicionales

CASE

Es una instrucción incorporada a la versión 9 de Oracle que permite establecer condiciones de salida (al estilo if-then-else de muchos lenguajes). Sintaxis:

CASE expresión WHEN valor1 THEN resultado1
[ WHEN valor2 THEN resultado2 ....
...
ELSE resultadoElse
]
END

El funcionamiento es el siguiente:

1> Se evalúa la expresión indicada
2> Se comprueba si esa expresión es igual al valor del primer WHEN, de ser así se 
devuelve el primer resultado (cualquier valor excepto nulo)
3> Si la expresión no es igual al valor 1, entonces se comprueba si es igual que el segundo. De ser así se escribe el resultado 3. De no ser así se continua con el siguiente WHEN
4> El resultado indicado en la zona ELSE sólo se escribe si la expresión no vale ningún valor de los indicados. Ejemplo:

SELECT
CASE cotizacion WHEN 1 THEN salario*0.85
WHEN 2 THEN salario * 0.93
WHEN 3 THEN salario * 0.96
ELSE salario
END
FROM empleados;

DECODE

Similar a la anterior pero en forma de función. Se evalúa una expresión y se colocan a continuación pares valor, resultado de forma que si se la expresión equivale al valor, se obtiene el resultado indicado. Se puede indicar un último parámetro con el resultado a efectuar en caso de no encontrar ninguno de los valores indicados. Sintaxis:

DECODE(expresión, valor1, resultado1
[,valor2, resultado2,...]
[,valorPordefecto])

Ejemplo:

SELECT
DECODE(cotizacion,1, salario*0.85, 2,salario * 0.93, 3,salario * 0.96,salario)
FROM empleados;

Este ejemplo es idéntico al utilizado para la instrucción CASE.

Obtener datos de múltiples tablas 

Es más que habitual necesitar en una consulta datos que se encuentran distribuidos en varias tablas. Las bases de datos relacionales se basan en que los datos se distribuyen en tablas que se pueden relacionar mediante un campo. Ese campo es el que permite integrar los datos de las tablas. Por ejemplo si disponemos de una tabla de empleados cuya clave es el dni y otra tabla de tareas que se refiere a tareas realizadas por los empleados, es seguro (si el diseño está bien hecho) que en la tabla de tareas aparecerá el dni del empleado para saber qué empleado realizó la tarea.

Producto cruzado o cartesiano de tablas

En el ejemplo anterior si quiere obtener una lista de los datos de las tareas y los empleados, se podría hacer de esta forma:

SELECT cod_tarea, descripcion_tarea, dni_empleado, nombre_empleado
FROM tareas,empleados;

La sintaxis es correcta ya que, efectivamente, en el apartado FROM se pueden indicar varias tareas separadas por comas. Pero eso produce un producto cruzado, aparecerán todos los registros de las tareas relacionados con todos los registros de empleados. El producto cartesiano a veces es útil para realizar consultas complejas, pero en el caso normal no lo es. necesitamos discriminar ese producto para que sólo aparezcan los registros de las tareas relacionadas con sus empleados correspondientes. A eso se le llama asociar (join) tablas.

Asociando tablas

La forma de realizar correctamente la consulta anterior (asociado las tareas con los empleados que la realizaron sería:

SELECT cod_tarea, descripcion_tarea, dni_empleado, nombre_empleado
FROM tareas,empleados
WHERE tareas.dni_empleado = empleados.dni;

Nótese que se utiliza la notación tabla.columna para evitar la ambigüedad, ya que el mismo nombre de campo se puede repetir en ambas tablas. Para evitar repetir continuamente el nombre de la tabla, se puede utilizar un alias de tabla:

SELECT a.cod_tarea, a.descripcion_tarea, b.dni_empleado, b.nombre_empleado
FROM tareas a,empleados b
WHERE a.dni_empleado = b.dni;

Al apartado WHERE se le pueden añadir condiciones encadenándolas con el operador AND. Ejemplo:

SELECT a.cod_tarea, a.descripcion_tarea
FROM tareas a,empleados b
WHERE a.dni_empleado = b.dni AND b.nombre_empleado='Javier';

Finalmente indicar que se pueden enlazar más de dos tablas a través de sus campos relacionados. Ejemplo:

SELECT a.cod_tarea, a.descripcion_tarea, b.nombre_empleado, c.nombre_utensilio
FROM tareas a,empleados b, utensilios_utilizados c
WHERE a.dni_empleado = b.dni AND a.cod_tarea=c.cod_tarea;

Relaciones sin Igualdad

A las relaciones descritas anteriormente se las llama relaciones en igualdad (equijoins), ya
que las tablas se relacionan a través de campos que contienen valores iguales en dos tablas. A veces esto no ocurre, en las tablas:

















En el ejemplo anterior podríamos averiguar la categoría a la que pertenece cada empleado,pero estas tablas poseen una relación que ya no es de igualdad. La forma sería:

SELECT a.empleado, a.sueldo, b.categoria
FROM empleados a, categorias b
WHERE a.sueldo between b.sueldo_minimo and b.sueldo_maximo;

Obtener registros no relacionados

En el ejemplo visto anteriormente de las tareas y los empleados. Podría ocurrir que un empleado no hubiera realizado una tarea todavía, con lo que habría empleados que no aparecerían en la consulta al no tener una tarea relacionada.

La forma de conseguir que salgan todos los registros de una tabla aunque no estén relacionados con las de otra es realizar una asociación lateral o unión externa (también llamada outer join). En esas asociaciones, el signo (+) indica que se desean todos los registros de la tabla estén o no relacionados. Sintaxis:

SELECT tabla1.columna1, tabla1.columna2,....
tabla2.columna1, tabla2.columna2,...
FROM tabla1, tabla2
WHERE tabla1.columnaRelacionada(+)=tabla2.columnaRelacionada

Eso obtiene los registros relacionados entre las tablas y además los registros no relacionados de la tabla2. Se podría usar esta otra forma:

SELECT tabla1.columna1, tabla1.columna2,....
tabla2.columna1, tabla2.columna2,...
FROM tabla1, tabla2
WHERE tabla1.columnaRelacionada=tabla2.columnaRelacionada(+)

En ese caso salen los relacionados y los de la primera tabla que no estén relacionados con ninguno de la primera.

Sintaxis SQL 1999

En la versión SQL de 1999 se ideó una nueva sintaxis para consultar varias tablas. La 
razón fue separar las condiciones de asociación respecto de las condiciones de selección de 
registros. La sintaxis completa es:

SELECT tabla1.columna1, tabl1.columna2,...
tabla2.columna1, tabla2.columna2,... FROM tabla1
[CROSS JOIN tabla2]|
[NATURAL JOIN tabla2]|
[JOIN tabla2 USING(columna)]|
[JOIN tabla2 ON (tabla1.columa=tabla2.columna)]|
[LEFT|RIGHT|FULL OUTER JOIN tabla2 ON
(tabla1.columa=tabla2.columna)]

Se describen sus posibilidades

CROSS JOIN
Utilizando la opción CROSS JOIN se realiza un producto cruzado entre las tablas indicadas

NATURAL JOIN
Establece una relación de igualdad entre las tablas a través de los campos que tengan el
mismo nombre en ambas tablas:

SELECT * FROM piezas
NATURAL JOIN existencias;

En el ejemplo anterior se obtienen los registros de piezas relacionados en existencias a través de los campos que tengan el mismo nombre en ambas tablas.

JOIN USING
Permite establecer relaciones indicando qué campo (o campos) común a las dos tablas hay que utilizar:

SELECT * FROM piezas
JOIN existencias USING(tipo,modelo);

JOIN ON
Permite establecer relaciones cuya condición se establece manualmente, lo que permite realizar asociaciones más complejas o bien asociaciones cuyos campos en las tablas no tienen el mismo nombre:

SELECT * FROM piezas
JOIN existencias ON(piezas.tipo=existencias.tipo AND
piezas.modelo=existencias.modelo);

relaciones externas
La última posibilidad es obtener relaciones laterales o externas (outer join). Para ello se utiliza la sintaxis:

SELECT * FROM piezas
LEFT OUTER JOIN existencias
ON(piezas.tipo=existencias.tipo AND
piezas.modelo=existencias.modelo);

En este consulta además de las relacionadas, aparecen las piezas no relacionadas en existencias. Si el LEFT lo cambiamos por un RIGHT, aparecerán las existencias no presentes en piezas. La condición FULL OUTER JOIN produciría un resultado en el que aparecen los registros no relacionados de ambas tablas.



No hay comentarios:

Publicar un comentario