Está en la página 1de 94

INSTITUTO TECNOLGICO SUPERIOR DE CINTALAPA

Materia: FUNDAMENTOS DE BASES DE DATOS

Catedrtico: LUIS GERMAN MONTESINOS ALFARO

UNIDAD 6

Tema: Lenguaje SQL Nombre del alumno: KALID ENMANUEL CORTOIS DOMINGUEZ

5 SEMESTRE

GRUPO: H

CINTALAPA DE FIGUEROA CHIAPAS A 26 DE NOVIEMBRE DEL 2012

Lenguaje SQL. Introduccin Bases de datos-SQL-Sentencias SQL-Introduccin El lenguaje de consulta estructurado (SQL) es un lenguaje de base de datos normalizado, utilizado por los diferentes motores de bases de datos para realizar determinadas operaciones sobre los datos o sobre la estructura de los mismos. Pero como sucede con cualquier sistema de normalizacin hay excepciones para casi todo; de hecho, cada motor de bases de datos tiene sus peculiaridades y lo hace diferente de otro motor, por lo tanto, el lenguaje SQL normalizado (ANSI) no nos servir para resolver todos los problemas, aunque si se puede asegurar que cualquier sentencia escrita en ANSI ser interpretable por cualquier motor de datos. Breve Historia La historia de SQL (que se pronuncia deletreando en ingls las letras que lo componen, es decir "ese-cu-ele" y no "siquel" como se oye a menudo) empieza en 1974 con la definicin, por parte de Donald Chamberlin y de otras personas que trabajaban en los laboratorios de investigacin de IBM, de un lenguaje para la especificacin de las caractersticas de las bases de datos que adoptaban el modelo relacional. Este lenguaje se llamaba SEQUEL (Structured English Query Language) y se implement en un prototipo llamado SEQUELXRM entre 1974 y 1975. Las experimentaciones con ese prototipo condujeron, entre 1976 y 1977, a una revisin del lenguaje (SEQUEL/2), que a partir de ese momento cambi de nombre por motivos legales, convirtindose en SQL. El prototipo (System R), basado en este lenguaje, se adopt y utiliz internamente en IBM y lo adoptaron algunos de sus clientes elegidos. Gracias al xito de este sistema, que no estaba todava comercializado, tambin otras compaas empezaron a desarrollar sus productos relacionales basados en SQL. A partir de 1981, IBM comenz a entregar sus productos relacionales y en 1983 empez a vender DB2. En el curso de los aos ochenta, numerosas compaas (por ejemplo Oracle y Sybase, slo por citar algunos) comercializaron productos basados en SQL, que se convierte en el estndar industrial de hecho por lo que respecta a las bases de datos relacionales. En 1986, el ANSI adopt SQL (sustancialmente adopt el dialecto SQL de IBM) como estndar para los lenguajes relacionales y en 1987 se transfom en estndar ISO. Esta versin del estndar va con el nombre de SQL/86. En los aos siguientes, ste ha sufrido diversas revisiones que han conducido primero a la versin SQL/89 y, posteriormente, a la actual SQL/92. El hecho de tener un estndar definido por un lenguaje para bases de datos relacionales abre potencialmente el camino a la intercomunicabilidad entre todos los productos que se basan en l. Desde el punto de vista prctico, por desgracia las cosas fueron de otro modo. Efectivamente, en general cada productor adopta e implementa en la propia base de datos slo el corazn del lenguaje SQL (el as llamado Entry level o al mximo el Intermediate level),

extendindolo de manera individual segn la propia visin que cada cual tenga del mundo de las bases de datos. Actualmente, est en marcha un proceso de revisin del lenguaje por parte de los comits ANSI e ISO, que debera terminar en la definicin de lo que en este momento se conoce como SQL3. Las caractersticas principales de esta nueva encarnacin de SQL deberan ser su transformacin en un lenguaje standalone (mientras ahora se usa como lenguaje hospedado en otros lenguajes) y la introduccin de nuevos tipos de datos ms complejos que permitan, por ejemplo, el tratamiento de datos multimediales. Componentes del SQL El lenguaje SQL est compuesto por comandos, clusulas, operadores y funciones de agregado. Estos elementos se combinan en las instrucciones para crear, actualizar y manipular las bases de datos. Comandos Existen dos tipos de comandos SQL:
o DLL que permiten crear y definir nuevas bases de datos, campos e

ndices. o DML que permiten generar consultas para ordenar, filtrar y extraer datos de la base de datos. Comandos DLL Comando Descripcin CREATE DROP ALTER Utilizado para crear nuevas tablas, campos e ndices Empleado para eliminar tablas e ndices Utilizado para modificar las tablas agregando campos o cambiando la definicin de los campos. Comandos DML Comando Descripcin SELECT INSERT UPDATE DELETE Utilizado para consultar registros de la base de datos que satisfagan un criterio determinado Utilizado para cargar lotes de datos en la base de datos en una nica operacin. Utilizado para modificar los valores de los campos y registros especificados Utilizado para eliminar registros de una tabla de una base de datos

Clusulas Las clusulas son condiciones de modificacin utilizadas para definir los datos que desea seleccionar o manipular. Clusula FROM WHERE GROUP BY HAVING ORDER BY Descripcin Utilizada para especificar la tabla de la cual se van a seleccionar los registros Utilizada para especificar las condiciones que deben reunir los registros que se van a seleccionar Utilizada para separar los registros seleccionados en grupos especficos Utilizada para expresar la condicin que debe satisfacer cada grupo Utilizada para ordenar los registros acuerdo con un orden especfico seleccionados de

Operadores Lgicos Operador Uso AND OR NOT Es el "y" lgico. Evala dos condiciones y devuelve un valor de verdad slo si ambas son ciertas. Es el "o" lgico. Evala dos condiciones y devuelve un valor de verdad si alguna de las dos es cierta. Negacin lgica. Devuelve el valor contrario de la expresin.

Operadores de Comparacin Operador < > <> <= >= = BETWEEN LIKE Uso Menor que Mayor que Distinto de Menor o igual que Mayor o igual que Igual que Utilizado para especificar un intervalo de valores. Utilizado en la comparacin de un modelo

In

Utilizado para especificar registros de una base de datos

Funciones de Agregado Las funciones de agregado se usan dentro de una clusula SELECT en grupos de registros para devolver un nico valor que se aplica a un grupo de registros. Funcinn Descripcin AVG COUNT SUM MAX MIN Utilizada para calcular el promedio de los valores de un campo determinado Utilizada para devolver el nmero de registros de la seleccin Utilizada para devolver la suma de todos los valores de un campo determinado Utilizada para devolver el valor ms alto de un campo especificado Utilizada para devolver el valor ms bajo de un campo especificado

Orden de ejecucin de los comandos Dada una sentencia SQL de seleccin que incluye todas las posibles clusulas, el orden de ejecucin de las mismas es el siguiente: 1. 2. 3. 4. 5. 6. Clusula Clusula Clusula Clusula Clusula Clusula FROM WHERE GROUP BY HAVING SELECT ORDER BY

Definicin de datos. Tipos de Datos Bases de datos-SQL-Sentencias SQL-Tipos de Datos Los tipos de datos SQL se clasifican en 13 tipos de datos primarios y de varios sinnimos vlidos reconocidos por dichos tipos de datos. Los tipos de datos primarios son: Tipo Datos de Longitud Descripcin

BINARY BIT BYTE COUNTER CURRENCY DATETIME

1 byte 1 byte 1 byte 4 bytes 8 bytes 8 bytes

Para consultas sobre tabla adjunta de productos de bases de datos que definen un tipo de datos Binario. Valores Si/No True/False Un valor entero entre 0 y 255. Un nmero incrementado automticamente (de tipo Long) Un entero escalable 922.337.203.685.477,5808 922.337.203.685.477,5807. entre y

Un valor de fecha u hora entre los aos 100 y 9999. Un valor en punto flotante de precisin simple con un rango de - 3.402823*1038 a 1.401298*10-45 para valores negativos, 1.401298*10- 45 a 3.402823*1038 para valores positivos, y 0. Un valor en punto flotante de doble precisin con un rango de - 1.79769313486232*10308 a 4.94065645841247*10-324 para valores negativos, 4.94065645841247*10-324 a 1.79769313486232*10308 para valores positivos, y 0. Un entero corto entre -32,768 y 32,767. Un entero largo 2,147,483,647. entre -2,147,483,648 y

SINGLE

4 bytes

DOUBLE

8 bytes

SHORT LONG LONGTEXT LONGBINARY TEXT

2 bytes 4 bytes

1 byte por De cero a un mximo de 1.2 gigabytes. carcter Segn se De cero 1 gigabyte. Utilizado para objetos OLE. necesite 1 byte por De cero a 255 caracteres. carcter

La siguiente tabla recoge los sinnimos de los tipos de datos definidos: Tipo de Dato BINARY Sinnimos VARBINARY

BIT BYTE COUNTER CURRENCY DATETIME

BOOLEAN LOGICAL LOGICAL1 YESNO INTEGER1 AUTOINCREMENT MONEY DATE TIME TIMESTAMP FLOAT4 IEEESINGLE REAL FLOAT FLOAT8 IEEEDOUBLE NUMBER NUMERIC INTEGER2 SMALLINT INT INTEGER INTEGER4 GENERAL OLEOBJECT LONGCHAR MEMO NOTE ALPHANUMERIC CHAR STRING - VARCHAR VALUE CHARACTER

SINGLE

DOUBLE

SHORT LONG LONGBINARY LONGTEXT

TEXT VARIANT (No Admitido)

Estructura bsica de las consultas. Consultas de Seleccin

Bases de datos-SQL-Sentencias SQL-Consultas de Seleccin

Las consultas de seleccin se utilizan para indicar al motor de datos que devuelva informacin de las bases de datos, esta informacin es devuelta en forma de conjunto de registros que se pueden almacenar en un objeto recordset. Este conjunto de registros puede ser modificable. Consultas bsicas La sintaxis bsica de una consulta de seleccin es la siguiente: SELECT FROM Campos Tabla

En donde campos es la lista de campos que se deseen recuperar y tabla es el origen de los mismos, por ejemplo: SELECT FROM Nombre, Telfono Clientes

Esta sentencia devuelve un conjunto de resultados con el campo nombre y telfono de la tabla clientes. Devolver Literales En determinadas ocasiones nos puede interesar incluir una columna con un texto fijo en una consulta de seleccin, por ejemplo, supongamos que tenemos una tabla de empleados y deseamos recuperar las tarifas semanales de los electricistas, podramos realizar la siguiente consulta: SELECT FROM WHERE Empleados.Nombre, 'Tarifa semanal: ', Empleados.TarifaHora * 40 Empleados Empleados.Cargo = 'Electricista'

Ordenar los registros Adicionalmente se puede especificar el orden en que se desean recuperar los registros de las tablas mediante la clusula ORDER BY Lista de Campos. En donde Lista de campos representa los campos a ordenar. Ejemplo: SELECT FROM CodigoPostal, Nombre, Telefono

Clientes ORDER BY Nombre Esta consulta devuelve los campos CodigoPostal, Nombre, Telefono de la tabla Clientes ordenados por el campo Nombre. Se pueden ordenar los registros por mas de un campo, como por ejemplo: SELECT FROM CodigoPostal, Nombre, Telefono

Clientes ORDER BY CodigoPostal, Nombre Incluso se puede especificar el orden de los registros: ascendente mediante la clusula (ASC - se toma este valor por defecto) descendente (DESC) SELECT FROM CodigoPostal, Nombre, Telefono

Clientes ORDER BY CodigoPostal DESC , Nombre ASC Uso de Indices de las tablas Si deseamos que la sentecia SQL utilice un ndice para mostrar los resultados se puede utilizar la palabra reservada INDEX de la siguiente forma: SELECT ... FROM Tabla (INDEX=Indice) ... Normalmente los motores de las bases de datos deciden que indice se debe utilizar para la consulta, para ello utilizan criterios de rendimiento y sobre todo los campos de bsqueda especificados en la clusula WHERE. Si se desea forzar a no utilizar ningn ndice utilizaremos la siguiente sintaxis: SELECT ... FROM Tabla (INDEX=0) ... Consultas con Predicado El predicado se incluye entre la clusula y el primer nombre del campo a recuperar, los posibles predicados son: Predicado ALL Descripcin Devuelve todos los campos de la tabla

TOP DISTINCT DISTINCTOW ALL

Devuelve un determinado nmero de registros de la tabla Omite los registros cuyos campos seleccionados coincidan totalmente Omite los registros duplicados basandose en la totalidad del registro y no slo en los campos seleccionados.

Si no se incluye ninguno de los predicados se asume ALL. El Motor de base de datos selecciona todos los registros que cumplen las condiciones de la instruccin SQL y devuelve todos y cada uno de sus campos. No es conveniente abusar de este predicado ya que obligamos al motor de la base de datos a analizar la estructura de la tabla para averiguar los campos que contiene, es mucho ms rpido indicar el listado de campos deseados. SELECT ALL FROM Empleados SELECT * FROM Empleados TOP Devuelve un cierto nmero de registros que entran entre al principio o al final de un rango especificado por una clusula ORDER BY. Supongamos que queremos recuperar los nombres de los 25 primeros estudiantes del curso 1994: SELECT TOP 25 Nombre, Apellido FROM Estudiantes ORDER BY Nota DESC Si no se incluye la clusula ORDER BY, la consulta devolver un conjunto arbitrario de 25 registros de la tabla de Estudiantes. El predicado TOP no elige entre valores iguales. En el ejemplo anterior, si la nota media nmero 25 y la 26 son iguales, la consulta devolver 26 registros. Se puede utilizar la palabra reservada PERCENT para devolver un cierto porcentaje de registros que caen al principio o al final de un rango especificado por la clusula ORDER BY. Supongamos que en lugar de los 25 primeros estudiantes deseamos el 10 por ciento del curso: SELECT TOP 10 PERCENT

Nombre, Apellido FROM Estudiantes ORDER BY Nota DESC El valor que va a continuacin de TOP debe ser un entero sin signo. TOP no afecta a la posible actualizacin de la consulta. DISTINCT Omite los registros que contienen datos duplicados en los campos seleccionados. Para que los valores de cada campo listado en la instruccin SELECT se incluyan en la consulta deben ser nicos. Por ejemplo, varios empleados listados en la tabla Empleados pueden tener el mismo apellido. Si dos registros contienen Lpez en el campo Apellido, la siguiente instruccin SQL devuelve un nico registro: SELECT DISTINCT Apellido FROM Empleados Con otras palabras el predicado DISTINCT devuelve aquellos registros cuyos campos indicados en la clusula SELECT posean un contenido diferente. El resultado de una consulta que utiliza DISTINCT no es actualizable y no refleja los cambios subsiguientes realizados por otros usuarios. DISTINCTROW Este predicado no es compatible con ANSI. Que yo sepa a da de hoy slo funciona con ACCESS. Devuelve los registros diferentes de una tabla; a diferencia del predicado anterior que slo se fijaba en el contenido de los campos seleccionados, ste lo hace en el contenido del registro completo independientemente de los campos indicados en la clusula SELECT. SELECT DISTINCTROW Apellido FROM Empleados Si la tabla empleados contiene dos registros: Antonio Lpez y Marta Lpez el ejemplo del predicado DISTINCT devuelve un nico registro con el valor Lpez en el campo Apellido ya que busca no duplicados en dicho campo. Este ltimo ejemplo devuelve dos registros con el valor Lpez en el apellido ya que se buscan no duplicados en el registro completo.

ALIAS En determinadas circunstancias es necesario asignar un nombre a alguna columna determinada de un conjunto devuelto, otras veces por simple capricho o porque estamos recuperando datos de diferentes tablas y resultan tener un campo con igual nombre. Para resolver todas ellas tenemos la palabra reservada AS que se encarga de asignar el nombre que deseamos a la columna deseada. Tomado como referencia el ejemplo anterior podemos hacer que la columna devuelta por la consulta, en lugar de llamarse apellido (igual que el campo devuelto) se llame Empleado. En este caso procederamos de la siguiente forma: SELECT DISTINCTROW Apellido AS Empleado FROM Empleados AS no es una palabra reservada de ANSI, existen diferentes sistemas de asignar los alias en funcin del motor de bases de datos. En ORACLE para asignar un alias a un campo hay que hacerlo de la siguiente forma: SELECT Apellido AS "Empleado" FROM Empleados Tambin podemos asignar alias a las tablas dentro de la consulta de seleccin, en esta caso hay que tener en cuenta que en todas las referencias que deseemos hacer a dicha tabla se ha de utilizar el alias en lugar del nombre. Esta tcnica ser de gran utilidad ms adelante cuando se estudien las vinculaciones entre tablas. Por ejemplo: SELECT FROM Apellido AS Empleado Empleados AS Trabajadores

Para asignar alias a las tablas en ORACLE y SQL-SERVER los alias se asignan escribiendo el nombre de la tabla, dejando un espacio en blanco y escribiendo el Alias (se asignan dentro de la clusula FROM). SELECT FROM
(1)

Trabajadores.Apellido

(1)

AS Empleado

Empleados Trabajadores

Esta nomenclatura [Tabla].[Campo] se debe utilizar cuando se est recuperando un campo cuyo nombre se repite en varias de las tablas que se utilizan en la sentencia. No obstante cuando en la sentencia se emplean varias tablas es aconsejable utilizar esta nomenclatura para evitar el trabajo que

supone al motor de datos averiguar en que tabla est cada uno de los campos indicados en la clusua SELECT. Recuperar Informacin de una base de Datos Externa Para concluir este captulo se debe hacer referencia a la recuperacin de registros de bases de datos externas. Es ocasiones es necesario la recuperacin de informacin que se encuentra contenida en una tabla que no se encuentra en la base de datos que ejecutar la consulta o que en ese momento no se encuentra abierta, esta situacin la podemos salvar con la palabra reservada IN de la siguiente forma: SELECT FROM Apellido AS Empleado Empleados IN'c: \databases\gestion.mdb'

En donde c: \databases\gestion.mdb es la base de datos que contiene la tabla Empleados. Esta tcnica es muy sencilla y comn en bases de datos de tipo ACCESS en otros sistemas como SQL-SERVER u ORACLE, la cosa es ms complicada la tener que existir relaciones de confianza entre los servidores o al ser necesaria la vinculacin entre las bases de datos. Este ejemplo recupera la informacin de una base de datos de SQL-SERVER ubicada en otro servidor (se da por supuesto que los servidores estn lincados): SELECT FROM Apellido Servidor1.BaseDatos1.dbo.Empleados

Consultas de Accin

Bases de datos-SQL-Sentencias SQL-Consultas de Accin Las consultas de accin son aquellas que no devuelven ningn registro, son las encargadas de acciones como aadir y borrar y modificar registros. Tanto las sentencias de actualizacin como las de borrado desencadern (segn el motor de datos) las actualizaciones en cascada, borrados en cascada, restricciones y valores por defecto definidos para los diferentes campos o tablas afectadas por la consulta. DELETE

Crea una consulta de eliminacin que elimina los registros de una o ms de las tablas listadas en la clusula FROM que satisfagan la clusula WHERE. Esta consulta elimina los registros completos, no es posible eliminar el contenido de algn campo en concreto. Su sintaxis es: DELETE FROM Tabla WHERE criterio Una vez que se han eliminado los registros utilizando una consulta de borrado, no puede deshacer la operacin. Si desea saber qu registros se eliminarn, primero examine los resultados de una consulta de seleccin que utilice el mismo criterio y despus ejecute la consulta de borrado. Mantenga copias de seguridad de sus datos en todo momento. Si elimina los registros equivocados podr recuperarlos desde las copias de seguridad. DELETE FROM WHERE

Empleados Cargo = 'Vendedor'

INSERT INTO Agrega un registro en una tabla. Se la conoce como una consulta de datos aadidos. Esta consulta puede ser de dos tipo: Insertar un nico registro Insertar en una tabla los registros contenidos en otra tabla. Para insertar un nico Registro: En este caso la sintaxis es la siguiente: INSERT INTO Tabla (campo1, campo2, ..., campoN) VALUES (valor1, valor2, ..., valorN) Esta consulta graba en el campo1 el valor1, en el campo2 y valor2 y as sucesivamente. Para seleccionar registros e insertarlos en una tabla nueva En este caso la sintaxis es la siguiente: SELECT campo1, campo2, ..., campoN INTO nuevatabla FROM tablaorigen [WHERE criterios] Se pueden utilizar las consultas de creacin de tabla para archivar registros, hacer copias de seguridad de las tablas o hacer copias para exportar a otra base de datos o utilizar en informes que muestren los datos de un periodo de tiempo concreto. Por ejemplo, se podra crear un informe de Ventas mensuales por regin ejecutando la misma consulta de creacin de tabla cada mes.

Para insertar Registros de otra Tabla: En este caso la sintaxis es: INSERT INTO Tabla [IN base_externa] (campo1, campo2, , campoN) SELECT TablaOrigen.campo1, TablaOrigen.campo2,,TablaOrigen.campoN FROM Tabla Origen En este caso se seleccionarn los campos 1,2,..., n de la tabla origen y se grabarn en los campos 1,2,.., n de la Tabla. La condicin SELECT puede incluir la clusula WHERE para filtrar los registros a copiar. Si Tabla y Tabla Origen poseen la misma estructura podemos simplificar la sintaxis a: INSERT INTO Tabla SELECT Tabla Origen.* FROM Tabla Origen De esta forma los campos de Tabla Origen se grabarn en Tabla, para realizar esta operacin es necesario que todos los campos de Tabla Origen estn contenidos con igual nombre en Tabla. Con otras palabras que Tabla posea todos los campos de Tabla Origen (igual nombre e igual tipo). En este tipo de consulta hay que tener especial atencin con los campos contadores o autonumricos puesto que al insertar un valor en un campo de este tipo se escribe el valor que contenga su campo homlogo en la tabla origen, no incrementndose como le corresponde. Se puede utilizar la instruccin INSERT INTO para agregar un registro nico a una tabla, utilizando la sintaxis de la consulta de adicin de registro nico tal y como se mostr anteriormente. En este caso, su cdigo especifica el nombre y el valor de cada campo del registro. Debe especificar cada uno de los campos del registro al que se le va a asignar un valor as como el valor para dicho campo. Cuando no se especifica dicho campo, se inserta el valor predeterminado o Null. Los registros se agregan al final de la tabla. Tambin se puede utilizar INSERT INTO para agregar un conjunto de registros pertenecientes a otra tabla o consulta utilizando la clusula SELECT... FROM como se mostr anteriormente en la sintaxis de la consulta de adicin de mltiples registros. En este caso la clusula SELECT especifica los campos que se van a agregar en la tabla destino especificada. La tabla destino u origen puede especificar una tabla o una consulta. Si la tabla destino contiene una clave principal, hay que asegurarse que es nica, y con valores no nulos; si no es as, no se agregarn los registros. Si se agregan registros a una tabla con un campo Contador, no se debe incluir el campo Contador en la consulta. Se puede emplear la clusula IN para agregar registros a una tabla en otra base de datos. Se pueden averiguar los registros que se agregarn en la consulta ejecutando primero una consulta de seleccin que utilice el mismo criterio de seleccin y

ver el resultado. Una consulta de adicin copia los registros de una o ms tablas en otra. Las tablas que contienen los registros que se van a agregar no se vern afectadas por la consulta de adicin. En lugar de agregar registros existentes en otra tabla, se puede especificar los valores de cada campo en un nuevo registro utilizando la clusula VALUES. Si se omite la lista de campos, la clusula VALUES debe incluir un valor para cada campo de la tabla, de otra forma fallar INSERT. Ejemplos INSERT INTO Clientes SELECT ClientesViejos.* FROM ClientesNuevos SELECT Empleados.* INTO Programadores FROM Empleados WHERE Categoria = 'Programador' Esta consulta crea una tabla nueva llamada programadores con igual estructura que la tabla empleado y copia aquellos registros cuyo campo categoria se programador INSERT INTO Empleados (Nombre, Apellido, Cargo) VALUES ( 'Luis', 'Snchez', 'Becario' ) INSERT INTO Empleados SELECT Vendedores.* FROM Vendedores WHERE Provincia = 'Madrid' UPDATE Crea una consulta de actualizacin que cambia los valores de los campos de una tabla especificada basndose en un criterio especfico. Su sintaxis es: UPDATE Tabla SET Campo1=Valor1, Campo2=Valor2, CampoN=ValorN WHERE Criterio

UPDATE es especialmente til cuando se desea cambiar un gran nmero de registros o cuando stos se encuentran en mltiples tablas. Puede cambiar varios campos a la vez. El ejemplo siguiente incrementa los valores Cantidad pedidos en un 10 por ciento y los valores Transporte en un 3 por ciento para aquellos que se hayan enviado al Reino Unido.: UPDATE Pedidos SET Pedido = Pedidos * 1.1, Transporte = Transporte * 1.03 WHERE PaisEnvo = 'ES' UPDATE no genera ningn resultado. Para saber qu registros se van a cambiar, hay que examinar primero el resultado de una consulta de seleccin que utilice el mismo criterio y despus ejecutar la consulta de actualizacin. UPDATE Empleados SET Grado = 5 WHERE Grado = 2 UPDATE Productos SET Precio = Precio * 1.1 WHERE Proveedor = 8 AND Familia = 3 Si en una consulta de actualizacin suprimimos la clusula WHERE todos los registros de la tabla sealada sern actualizados. UPDATE Empleados SET Salario = Salario * 1.1

Consultas de Unin Internas

Bases de datos-SQL-Sentencias SQL-Consultas de Unin Internas

Consultas de Combinacin entre tablas Las vinculaciones entre tablas se realizan mediante la clusula INNER que combina registros de dos tablas siempre que haya concordancia de valores en un campo comn. Su sintaxis es: SELECT campos FROM tb1 INNER JOIN tb2 ON tb1.campo1 comp tb2.campo2 En donde: tb1, tb2 campo1, campo2 comp Son los nombres de las tablas desde las que se combinan los registros. Son los nombres de los campos que se combinan. Si no son numricos, los campos deben ser del mismo tipo de datos y contener el mismo tipo de datos, pero no tienen que tener el mismo nombre. Es cualquier operador de comparacin relacional: =, <,<>, <=, =>, >.

Se puede utilizar una operacin INNER JOIN en cualquier clusula FROM. Esto crea una combinacin por equivalencia, conocida tambin como unin interna. Las combinaciones equivalentes son las ms comunes; stas combinan los registros de dos tablas siempre que haya concordancia de valores en un campo comn a ambas tablas. Se puede utilizar INNER JOIN con las tablas Departamentos y Empleados para seleccionar todos los empleados de cada departamento. Por el contrario, para seleccionar todos los departamentos (incluso si alguno de ellos no tiene ningn empleado asignado) se emplea LEFT JOIN o todos los empleados (incluso si alguno no est asignado a ningn departamento), en este caso RIGHT JOIN. Si se intenta combinar campos que contengan datos Memo u Objeto OLE, se produce un error. Se pueden combinar dos campos numricos cualesquiera, incluso si son de diferente tipo de datos. Por ejemplo, puede combinar un campo Numrico para el que la propiedad Size de su objeto Field est establecida como Entero, y un campo Contador. El ejemplo siguiente muestra cmo podra combinar las tablas Categoras y Productos basndose en el campo IDCategoria: SELECT FROM NombreCategoria, NombreProducto Categorias INNER JOIN Productos

ON Categorias.IDCategoria = Productos.IDCategoria En el ejemplo anterior, IDCategoria es el campo combinado, pero no est incluido en la salida de la consulta ya que no est incluido en la instruccin SELECT. Para incluir el campo combinado, incluir el nombre del campo en la instruccin SELECT, en este caso, Categorias.IDCategoria. Tambin se pueden enlazar varias clusulas ON en una instruccin JOIN, utilizando la sintaxis siguiente: SELECT campos FROM tabla1 INNER JOIN tabla2 ON (tb1.campo1 comp tb2.campo1 AND ON tb1.campo2 comp tb2.campo2) OR ON (tb1.campo3 comp tb2.campo3) Tambin puede anidar instrucciones JOIN utilizando la siguiente sintaxis: SELECT campos FROM tb1 INNER JOIN (tb2 INNER JOIN [( ]tb3 [INNER JOIN [( ]tablax [INNER JOIN ...)] ON tb3.campo3 comp tbx.campox)] ON tb2.campo2 comp tb3.campo3) ON tb1.campo1 comp tb2.campo2 Un LEFT JOIN o un RIGHT JOIN puede anidarse dentro de un INNER JOIN, pero un INNER JOIN no puede anidarse dentro de un LEFT JOIN o un RIGHT JOIN. Ejemplo: SELECT DISTINCT Sum(PrecioUnitario * Cantidad) AS Sales, (Nombre + ' ' + Apellido) AS Name FROM Empleados INNER JOIN( Pedidos INNER JOIN DetallesPedidos ON Pedidos.IdPedido = DetallesPedidos.IdPedido) ON Empleados.IdEmpleado = Pedidos.IdEmpleado GROUP BY Nombre + ' ' + Apellido (Crea dos combinaciones equivalentes: una entre las tablas Detalles de pedidos y Pedidos, y la otra entre las tablas Pedidos y Empleados. Esto es necesario ya que la tabla Empleados no contiene datos de ventas y

la tabla Detalles de pedidos no contiene datos de los empleados. La consulta produce una lista de empleados y sus ventas totales.) Si empleamos la clusula INNER en la consulta se seleccionarn slo aquellos registros de la tabla de la que hayamos escrito a la izquierda de INNER JOIN que contengan al menos un registro de la tabla que hayamos escrito a la derecha. Para solucionar esto tenemos dos clusulas que sustituyen a la palabra clave INNER, estas clusulas son LEFT y RIGHT. LEFT toma todos los registros de la tabla de la izquierda aunque no tengan ningn registro en la tabla de la izquierda. RIGHT realiza la misma operacin pero al contrario, toma todos los registros de la tabla de la derecha aunque no tenga ningn registro en la tabla de la izquierda. La sintaxis expuesta anteriormente pertenece a ACCESS, en donde todas las sentencias con la sintaxis funcionan correctamente. Los manuales de SQLSERVER dicen que esta sintaxis es incorrecta y que hay que aadir la palabra reservada OUTER: LEFT OUTER JOIN y RIGHT OUTER JOIN. En la prctica funciona correctamente de una u otra forma. No obstante, los INNER JOIN ORACLE no es capaz de interpretarlos, pero existe una sintaxis en formato ANSI para los INNER JOIN que funcionan en todos los sistemas. Tomando como referencia la siguiente sentencia: SELECT Facturas.*, Albaranes.* Facturas INNER JOIN Albaranes ON Facturas.IdAlbaran = Albaranes.IdAlbaran Facturas.IdCliente = 325

FROM

WHERE

La transformacin de esta sentencia a formato ANSI sera la siguiente: SELECT Facturas.*, Albaranes.* Facturas, Albaranes Facturas.IdAlbaran = Albaranes.IdAlbaran AND Facturas.IdCliente = 325

FROM WHERE

Como se puede observar los cambios realizados han sido los siguientes:

1. Todas las tablas que intervienen en la consulta se especifican en la clusula FROM. 2. Las condiciones que vinculan a las tablas se especifican en la clusula WHERE y se vinculan mediante el operador lgico AND. Referente a los OUTER JOIN, no funcionan en ORACLE y adems conozco una sintaxis que funcione en los tres sistemas. La sintaxis en ORACLE es igual a la sentencia anterior pero aadiendo los caracteres (+) detrs del nombre de la tabla en la que deseamos aceptar valores nulos, esto equivale a un LEFT JOIN: SELECT Facturas.*, Albaranes.* Facturas, Albaranes Facturas.IdAlbaran = Albaranes.IdAlbaran (+) AND Facturas.IdCliente = 325

FROM WHERE

Y esto a un RIGHT JOIN: SELECT Facturas.*, Albaranes.* Facturas, Albaranes Facturas.IdAlbaran (+) = Albaranes.IdAlbaran AND Facturas.IdCliente = 325

FROM WHERE

En SQL-SERVER se puede utilizar una sintaxis parecida, en este caso no se utiliza los caracteres (+) sino los caracteres =* para el LEFT JOIN y *= para el RIGHT JOIN. Consultas de Autocombinacin La autocombinacin se utiliza para unir una tabla consigo misma, comparando valores de dos columnas con el mismo tipo de datos. La sintaxis en la siguiente: SELECT FROM WHERE alias1.columna, alias2.columna, ... tabla1 as alias1, tabla2 as alias2 alias1.columna = alias2.columna

AND

otras condiciones

Por ejemplo, para visualizar el nmero, nombre y puesto de cada empleado, junto con el nmero, nombre y puesto del supervisor de cada uno de ellos se utilizara la siguiente sentencia: SELECT FROM WHERE t.num_emp, t.nombre, t.puesto, t.num_sup,s.nombre, s.puesto empleados AS t, empleados AS s t.num_sup = s.num_emp

Consultas de Combinaciones no Comunes La mayora de las combinaciones estn basadas en la igualdad de valores de las columnas que son el criterio de la combinacin. Las no comunes se basan en otros operadores de combinacin, tales como NOT, BETWEEN, <>, etc. Por ejemplo, para listar el grado salarial, nombre, salario y puesto de cada empleado ordenando el resultado por grado y salario habra que ejecutar la siguiente sentencia: SELECT grados.grado,empleados.nombre, empleados.puesto empleados, grados grados.salarioinferior And empleados.salario,

FROM WHERE

empleados.salario BETWEEN grados.salariosuperior ORDER BY grados.grado, empleados.salario

Para listar el salario medio dentro de cada grado salarial habra que lanzar esta otra sentencia: SELECT FROM WHERE grados.grado, AVG(empleados.salario) empleados, grados BETWEEN grados.salarioinferior And

empleados.salario grados.salariosuperior GROUP BY grados.grado

CROSS JOIN (SQL-SERVER) Se utiliza en SQL-SERVER para realizar consultas de unin. Supongamos que tenemos una tabla con todos los autores y otra con todos los libros. Si deseramos obtener un listado combinar ambas tablas de tal forma que cada autor apareciera junto a cada ttulo, utilizaramos la siguiente sintaxis: SELECT FROM Autores.Nombre, Libros.Titulo Autores CROSS JOIN Libros

SELF JOIN SELF JOIN es una tcnica empleada para conseguir el producto cartesiano de una tabla consigo misma. Su utilizacin no es muy frecuente, pero pongamos algn ejemplo de su utilizacin. Supongamos la siguiente tabla (El campo autor es numrico, aunque para ilustrar el ejemplo utilice el nombre): Autores Cdigo (Cdigo del libro) B0012 B0012 B0012 C0014 C0014 D0120 D0120 Autor (Nombre del Autor) 1. Francisco Lpez 2. Javier Alonso 3. Marta Rebolledo 1. Francisco Lpez 2. Javier Alonso 2. Javier Alonso 3. Marta Rebolledo

Queremos obtener, para cada libro, parejas de autores: SELECT FROM WHERE A.Codigo, A.Autor, B.Autor Autores A, Autores B A.Codigo = B.Codigo

El resultado es el siguiente: Cdigo Autor Autor

B0012 B0012 B0012 B0012 B0012 B0012 B0012 B0012 B0012 C0014 C0014 C0014 C0014 D0120 D0120 D0120 D0120

1. Francisco Lpez 1. Francisco Lpez 1. Francisco Lpez 2. Javier Alonso 2. Javier Alonso 2. Javier Alonso 3. Marta Rebolledo 3. Marta Rebolledo 3. Marta Rebolledo 1. Francisco Lpez 1. Francisco Lpez 2. Javier Alonso 2. Javier Alonso 2. Javier Alonso 2. Javier Alonso 3. Marta Rebolledo 3. Marta Rebolledo

1. Francisco Lpez 2. Javier Alonso 3. Marta Rebolledo 2. Javier Alonso 1. Francisco Lpez 3. Marta Rebolledo 3. Marta Rebolledo 2. Javier Alonso 1. Francisco Lpez 1. Francisco Lpez 2. Javier Alonso 2. Javier Alonso 1. Francisco Lpez 2. Javier Alonso 3. Marta Rebolledo 3. Marta Rebolledo 2. Javier Alonso

Como podemos observar, las parejas de autores se repiten en cada uno de los libros, podemos omitir estas repeticiones de la siguiente forma SELECT FROM WHERE A.Codigo, A.Autor, B.Autor Autores A, Autores B A.Codigo = B.Codigo AND A.Autor < B.Autor

El resultado ahora es el siguiente: Cdigo B0012 B0012 C0014 D0120 Autor 1. Francisco Lpez 1. Francisco Lpez 1. Francisco Lpez 2. Javier Alonso Autor 2. Javier Alonso 3. Marta Rebolledo 2. Javier Alonso 3. Marta Rebolledo

Ahora tenemos un conjunto de resultados en formato Autor - CoAutor. Si en la tabla de empleados quisiramos extraer todas las posibles parejas que podemos realizar, utilizaramos la siguiente sentencia: SELECT FROM WHERE Hombres.Nombre, Mujeres.Nombre Empleados Hombre, Empleados Mujeres Hombre.Sexo = 'Hombre' AND Mujeres.Sexo = 'Mujer' AND Hombres.Id <>Mujeres.Id

Para concluir supongamos la tabla siguiente: Empleados Id 1 2 3 4 5 6 Marcos Lucas Ana Eva Juan Antonio Nombre 6 1 2 1 6 SuJefe

Queremos obtener un conjunto de resultados con el nombre del empleado y el nombre de su jefe: SELECT FROM WHERE Emple.Nombre, Jefes.Nombre Empleados Emple, Empleados Jefe Emple.SuJefe = Jefes.Id

FULL JOIN Este tipo de operador se utiliza para devolver todas las filas de una combinacin tengan o no correspondencia. Es el equivalente a la utilizacin de LEFT JOIN y RIGHT JOIN a la misma vez. Mediante este operador se obtendrn por un lado las filas que tengan correspondencia en ambas tablas y tambin aquellas que no tengan correspondencia sean de la tabla que sean.

Si desearamos obtener un listado que incluyera todos los autores con sus libros correspondientes, pero adems todos los autores que no han escrito ningn libro y todos aquellos libros sin autor (devemos suponer que no existe un autor llamado annimo): SELECT FROM ON Autores.*, Libros.* Autores FULL Libros Autores.IdAutor = Libros.IdAutor

Consultas de Unin Externas

Bases de datos-SQL-Sentencias SQL-Consultas de Unin Externas Se utiliza la operacin UNION para crear una consulta de unin, combinando los resultados de dos o ms consultas o tablas independientes. Su sintaxis es: [TABLE] consulta1 UNION [ALL] [TABLE] consulta2 [UNION [ALL] [TABLE] consultan [ ... ]] En donde: consulta 1,consulta consulta n Son instrucciones SELECT, el nombre de una consulta 2, almacenada o el nombre de una tabla almacenada precedido por la palabra clave TABLE.

Puede combinar los resultados de dos o ms consultas, tablas e instrucciones SELECT, en cualquier orden, en una nica operacin UNION. El ejemplo siguiente combina una tabla existente llamada Nuevas Cuentas y una instruccin SELECT: TABLE NuevasCuentas UNION ALL SELECT * FROM Clientes WHERE CantidadPedidos > 1000

Si no se indica lo contrario, no se devuelven registros duplicados cuando se utiliza la operacin UNION, no obstante puede incluir el predicado ALL para asegurar que se devuelven todos los registros. Esto hace que la consulta se ejecute ms rpidamente. Todas las consultas en una operacin UNION deben pedir el mismo nmero de campos, no obstante los campos no tienen porqu tener el mismo tamao o el mismo tipo de datos. Se puede utilizar una clusula GROUP BY y/o HAVING en cada argumento consulta para agrupar los datos devueltos. Puede utilizar una clusula ORDER BY al final del ltimo argumento consulta para visualizar los datos devueltos en un orden especfico. SELECT FROM WHERE UNION NombreCompania, Ciudad Proveedores Pais = 'Brasil'

SELECT NombreCompania, Ciudad FROM Clientes WHERE Pais = 'Brasil' (Recupera los nombres y las ciudades de todos proveedores y clientes de Brasil) SELECT NombreCompania, Ciudad FROM Proveedores WHERE Pais = 'Brasil' UNION SELECT NombreCompania, Ciudad FROM Clientes WHERE Pais = 'Brasil' ORDER BY Ciudad (Recupera los nombres y las ciudades de todos proveedores y clientes radicados en Brasil, ordenados por el nombre de la ciudad) SELECT NombreCompania, Ciudad FROM Proveedores WHERE Pais = 'Brasil' UNION SELECT NombreCompania, Ciudad FROM Clientes WHERE Pais = 'Brasil' UNION SELECT Apellidos, Ciudad

FROM Empleados WHERE Region = 'Amrica del Sur' (Recupera los nombres y las ciudades de todos los proveedores y clientes de brasil y los apellidos y las ciudades de todos los empleados de Amrica del Sur) TABLE Lista_Clientes UNION TABLE ListaProveedores (Recupera los nombres y cdigos de todos los proveedores y clientes)

Referencias Cruzadas

Bases de datos-SQL-Sentencias SQL-Referencias Cruzadas ACCESS Una consulta de referencias cruzadas es aquella que nos permite visualizar los datos en filas y en columnas, estilo tabla, por ejemplo: Producto / Ao Pantalones Camisas Zapatos 1996 1.250 8.560 4.369 1997 3.000 1.253 2.563

Si tenemos una tabla de productos y otra tabla de pedidos, podemos visualizar en total de productos pedidos por ao para un artculo determinado, tal y como se visualiza en la tabla anterior. La sintaxis para este tipo de consulta es la siguiente: TRANSFORM funcin agregada instruccin select PIVOT campo pivot [IN (valor1[, valor2[, ...]])] En donde: funcin agregada Es una funcin SQL agregada que opera sobre los datos seleccionados.

instruccin select campo pivot valor1, valor2

Es una instruccin SELECT. Es el campo o expresin que desea utilizar para crear las cabeceras de la columna en el resultado de la consulta. Son valores fijos utilizados para crear las cabeceras de la columna.

Para resumir datos utilizando una consulta de referencia cruzada, se seleccionan los valores de los campos o expresiones especificadas como cabeceras de columnas de tal forma que pueden verse los datos en un formato ms compacto que con una consulta de seleccin. TRANSFORM es opcional pero si se incluye es la primera instruccin de una cadena SQL. Precede a la instruccin SELECT que especifica los campos utilizados como encabezados de fila y una clusula GROUP BY que especifica el agrupamiento de las filas. Opcionalmente puede incluir otras clusulas como por ejemplo WHERE, que especifica una seleccin adicional o un criterio de ordenacin. Los valores devueltos en campo pivot se utilizan como encabezados de columna en el resultado de la consulta. Por ejemplo, al utilizar las cifras de ventas en el mes de la venta como pivot en una consulta de referencia cruzada se crearan 12 columnas. Puede restringir el campo pivot para crear encabezados a partir de los valores fijos (valor1, valor2) listados en la clusula opcional IN. Tambin puede incluir valores fijos, para los que no existen datos, para crear columnas adicionales. Ejemplos TRANSFORM Sum(Cantidad) AS Ventas SELECT Producto, Cantidad FROM Pedidos WHERE Fecha Between #01-01-1998# And #12-31-1998# GROUP BY Producto ORDER BY Producto PIVOT DatePart("m", Fecha)

(Crea una consulta de tabla de referencias cruzadas que muestra las ventas de productos por mes para un ao especfico. Los meses aparecen de izquierda a derecha como columnas y los nombres de los productos aparecen de arriba hacia abajo como filas.) TRANSFORM Sum(Cantidad) AS Ventas SELECT Compania FROM Pedidos WHERE Fecha Between #01-01-1998# And #12-31-1998# GROUP BY Compania ORDER BY Compania PIVOT "Trimestre " & DatePart("q", Fecha) In ('Trimestre1', 'Trimestre2', 'Trimestre 3', 'Trimestre 4') (Crea una consulta de tabla de referencias cruzadas que muestra las ventas de productos por trimestre de cada proveedor en el ao indicado. Los trimestres aparecen de izquierda a derecha como columnas y los nombres de los proveedores aparecen de arriba hacia abajo como filas.) Un caso prctico: Se trata de resolver el siguiente problema: tenemos una tabla de productos con dos campos, el cdigo y el nombre del producto, tenemos otra tabla de pedidos en la que anotamos el cdigo del producto, la fecha del pedido y la cantidad pedida. Deseamos consultar los totales de producto por ao, calculando la media anual de ventas. Estructura y datos de las tablas: ARTICULOS ID 1 2 3 Nombre Zapatos Pantalones Blusas ID 1 2 3 1 2 3 Fecha 11/11/1996 11/11/1996 11/11/1996 12/10/1996 04/10/1996 05/08/1996 PEDIDOS Cantidad 250 125 520 50 250 100

1 2 3 1 2 3

01/01/1997 02/08/1997 05/10/1997 12/12/1997 15/12/1997 17/10/1997

40 60 70 8 520 1.250

Para resolver la consulta planteamos la siguiente consulta: TRANSFORM Sum(Pedidos.Cantidad) AS Resultado SELECT Nombre AS Producto, Pedidos.Id AS Cdigo, Sum(Pedidos.Cantidad) AS TOTAL, Avg(Pedidos.Cantidad) AS Media FROM Pedidos, Artculos WHERE Pedidos.Id = Artculos.Id GROUP BY Pedidos.Id, Artculos.Nombre PIVOT Year(Fecha) Y obtenemos el siguiente resultado: Producto Zapatos Pantalones Blusas Cdigo 1 2 3 Total 348 955 1940 Media 87 238,75 485 1996 300 375 620 1997 48 580 1320

Comentarios a la consulta: La clusula TRANSFORM indica el valor que deseamos visualizar en las columnas que realmente pertenecen a la consulta, en este caso 1996 y 1997, puesto que las dems columnas son opcionales. SELECT especifica el nombre de las columnas opcionales que deseamos visualizar, en este caso Producto, Cdigo, Total y Media, indicando el nombre del campo que deseamos mostrar en cada columna o el valor de la misma. Si incluimos una funcin de clculo el resultado se har basndose en los datos de la fila actual y no al total de los datos.

FROM especifica el origen de los datos. La primera tabla que debe figurar es aquella de donde deseamos extraer los datos, esta tabla debe contener al menos tres campos, uno para los ttulos de la fila, otros para los ttulos de la columna y otro para calcular el valor de las celdas. En este caso en concreto se deseaba visualizar el nombre del producto, como en la tabla de pedidos slo figuraba el cdigo del mismo se aadi una nueva columna en la clusula select llamada Producto que se corresponda con el campo Nombre de la tabla de artculos. Para vincular el cdigo del artculo de la tabla de pedidos con el nombre del mismo de la tabla artculos se insert la clusula INNER JOIN. La clusula GROUP BY especifica el agrupamiento de los registros, contrariamente a los manuales de instruccin esta clusula no es opcional ya que debe figurar siempre y debemos agrupar los registros por el campo del cual extraemos la informacin. En este caso existen dos campos de los que extraemos la informacin: pedidos.cantidad y artculos.nombre, por ello agrupamos por los campos. Para finalizar la clusula PIVOT indica el nombre de las columnas no opcionales, en este caso 1996 y 1997 y como vamos a el dato que aparecer en las columnas, en este caso empleamos el ao en que se produjo el pedido, extrayndolo del campo pedidos.fecha. Otras posibilidades de fecha de la clusula pivot son las siguientes: 1. Para agrupamiento por Trimestres: PIVOT "Tri " & DatePart("q",[Fecha]); 2. Para agrupamiento por meses (sin tener en cuenta el ao) PIVOT Format([Fecha],"mmm") In ("Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"); 3. Para agrupar por das PIVOT Format([Fecha],"Short Date");

Operaciones con conjuntos. SQL Server 2005 permite tres tipos de operaciones con conjuntos:

UNION, disponible en todas las versiones de SQL Server. EXCEPT, nuevo en SQL Server 2005. INTERSECT, nuevo en SQL Server 2005. Para utilizar operaciones de conjuntos debemos cumplir una serie de normas.

Las consultas a unir deben tener el mismo nmero campos, y adems los campos deben ser del mismo tipo.

Slo puede haber una nica clausula ORDER BY al final de la sentencia SELECT. UNION UNION devuelve la suma de dos o ms conjuntos de resultados. El conjunto obtenido como resultado de UNION tiene la misma estructura que los conjuntos originales. El siguiente ejemplo muestra el uso de UNION

SELECT Nombre, Apellido1 , Apellido2, NifCif, FxNacimiento FROM EMPLEADOS UNION

SELECT Nombre, Apellido1 , Apellido2, NifCif, FxNacimiento FROM CLIENTES Cuando realizamos una consulta con UNION internamente se realiza una operacion DISTINCT sobre el conjunto de resultados final. Si queremos obtener todos los valores debemos utiliza UNION ALL.

SELECT Nombre, Apellido1 , Apellido2, NifCif, FxNacimiento FROM EMPLEADOS UNION

ALL SELECT Nombre, Apellido1 , Apellido2, NifCif, FxNacimiento FROM CLIENTES EXCEPT EXCEPT devuelve la diferencia (resta) de dos o ms conjuntos de resultados. El conjunto obtenido como resultado de EXCEPT tiene la misma estructura que los conjuntos originales. El siguiente ejemplo muestra el uso de EXCEPT

SELECT Nombre, Apellido1 , Apellido2, NifCif, FxNacimiento FROM EMPLEADOS EXCEPT SELECT Nombre, Apellido1 , Apellido2, NifCif, FxNacimiento FROM CLIENTES El uso de EXCEPT, como norma general, es mucho ms rpido que utilizar condiciones NOT IN o EXISTS en la clausula WHERE. INTERSECT Devuelve la interseccin entre dos o ms conjuntos de resultados en uno. El conjunto obtenido como resultado de INTERSECT tiene la misma estructura que los conjuntos originales.

El siguiente ejemplo muestra el uso de INTERSECT

SELECT Nombre, Apellido1 , Apellido2, NifCif, FxNacimiento FROM EMPLEADOS INTERSECT SELECT Nombre, Apellido1 , Apellido2, NifCif, FxNacimiento FROM CLIENTES

Operaciones de Conjuntos en SQL Server 2005 (UNION, EXCEPT, INRERSECT) Al trabajar con sistemas administradores de bases de datos (DBMS siglas en ingles de Database Management Systems) hemos ido heredando muchos conceptos de matematicas discretas y uno de ellos precisamente son las operaciones de conjuntos. Antes de entrar de lleno en el tema, es necesario hacer una visita a un concepto heredado de las matematicas que vamos a tratar aqui: las operaciones de conjuntos. Las operaciones aplicables tanto a un conjunto como a una tabla son las siguientes: Union, Interseccion, diferencia y diferencia simetrica como se observa en la tabla a continuacion

Como practica, Consideremos el caso siguiente: Tres cursos se impartieron en una escuela: Matematicas, Ingles, Historia y se necesita saber lo siguiente: 1) quienes han cursado al menos una materia 2)Quien ya curso todas 3)Quien no ha cursado matematicas Primero, creamos tres conjuntos de datos (o en este caso van a ser tablas temporales) y las llenamos con informacion create table #historia (nombre varchar(30)) create table #matematicas (nombre varchar(30)) create table #ingles (nombre varchar(30)) insert into #historia (nombre) values ('Luis Osorio') insert into #historia (nombre) values ('Martha Martinez') insert into #historia (nombre) values ('Daniel Gonzalez') insert into #historia (nombre) values ('Noemi Sanchez') insert into #ingles (nombre) values ('Luis Osorio') insert into #ingles (nombre) values ('Martha Martinez') insert into #ingles (nombre) values ('Daniel Gonzalez') insert into #ingles (nombre) values ('Cristal Lopez') insert into #Matematicas (nombre) values ('Luis Osorio') insert into #Matematicas (nombre) values ('Martha Martinez') insert into #Matematicas (nombre) values ('Noemi Sanchez') insert into #Matematicas (nombre) values ('Cristal Lopez') Despues, iremos respondiendo cada cuestionamiento. Empezamos con el #1, saber quienes han cursado al menos una materia. En este caso la operacion que realizariamos seria una union, en esta se utiliza el operador UNION de SQL Server con el cual combinariamos los resultados de tres queries en uno solo y tendriamos algo como esto:

Por defecto, UNION elimina los registros duplicados como se observo en el ejemplo anterior. Si se desea tener esos duplicados se puede especificar UNION ALL en nuestro ejemplo y con eso tendriamos de vuelta los registros duplicados, aunque generalmente lo que se requiere es no tener duplicidad de datos.

El siguiente caso a resolver es quien ya curso las tres materias. La operacion a realizar sera una interseccion ya que en este caso buscamos miembros de los tres conjuntos. El operador que usaremos ahora es INTERSECT, que retorna registros coincidentes en los tres queries de nuestro ejemplo dando como resultado lo siguiente:

Y finalmente, para saber quien no curso matematicas, usamos el operador EXCEPT el cual permite saber cuales "registros de A no estan en B", dicho de otra forma si tenemos la clases de Ingles e Historia y a esas clases les aplicamos el operador EXCEPT sabriamos quien ya llevo esas dos materias pero no ha llevado matematicas, el resultado de este ultimo se los presento a continuacion:

Esto es a grosso modo como funcionan las operaciones de conjunto en SQL Server 2005 y es como todo, bastante util si sabes donde usarlo y sacarle provecho y puedo decir a ciencia cierta que me ha sido util

Funciones de agregacin Las funciones de agregacin realizan anlisis estadsticos sobre nmeros (y tambin sobre fechas u horas para algunas funciones) en: varios campos de un registro. campos relacionados tanto si se muestran en un portal como si no. campos repetidos. Por ejemplo, puede utilizar la funcin Sum para sumar los valores que aparecen en un portal, como alternativa a la creacin de un informe con datos agrupados y subtotales.

Los valores del parmetro pueden incluir una constante numrica (por ejemplo, 10) o cualquier expresin vlida. Un parmetro constante en una frmula para un campo repetido afecta al resultado de cada repeticin. Si los parmetros de campo repetido (campo1; campo2;...) incluyen un campo no repetido, dicho valor se utiliza en el resultado slo para la primera repeticin a menos que utilice la Extend function. Los valores en repeticiones que superen el nmero de repeticiones del campo calculado se ignoran. Por ejemplo, un campo calculado con tres repeticiones slo guarda tres resultados, aunque un campo referenciado en el clculo tuviera cinco repeticiones. Haga clic en un nombre de funcin para obtener ms informacin. Esta funcin Devuelve Average La media de todos los valores vlidos y que no estn en blanco del campo especificado. El nmero de valores vlidos y que no estn en blanco del campo especificado. La concatenacin de todos los valores que no estn en blanco en un formulario de lista, separados por retornos de carro. El valor vlido ms alto de uno o varios campos.

Count

List

Max

Min

El valor vlido y que no est en blanco ms bajo de uno o varios campos.

StDev

La desviacin tpica de una serie de valores vlidos que no estn en blanco de uno o varios campos. La desviacin tpica de una poblacin representada por una serie de valores vlidos que no estn en blanco de uno o varios campos.

StDevP

Sum

El total de todos los valores vlidos que no estn en blanco de los campos especificados. La varianza de una serie de valores vlidos que no estn en blanco de uno o varios campos. La varianza de una poblacin de una serie de valores vlidos que no estn en blanco de uno o varios campos.

Variance

VarianceP

Agrupamiento de Registros GROUP BY Combina los registros con valores idnticos, en la lista de campos especificados, en un nico registro. Para cada registro se crea un valor sumario si se incluye una funcin SQL agregada, como por ejemplo Sum o Count, en la instruccin SELECT. Su sintaxis es: SELECT campos FROM tabla WHERE criterio GROUP BY campos del grupo GROUP BY es opcional. Los valores de resumen se omiten si no existe una funcin SQL agregada en la instruccin SELECT. Los valores Null en los campos GROUP BY se agrupan y no se omiten. No obstante, los valores Null no se evalan en ninguna de las funciones SQL agregadas. Se utiliza la clusula WHERE para excluir aquellas filas que no desea agrupar, y la clusula HAVING para filtrar los registros una vez agrupados. A menos que contenga un dato Memo u Objeto OLE, un campo de la lista de campos GROUP BY puede referirse a cualquier campo de las tablas que aparecen en la clusula FROM, incluso si el campo no esta incluido en la instruccin SELECT, siempre y cuando la instruccin SELECT incluya al menos una funcin SQL agregada. Todos los campos de la lista de campos de SELECT deben o bien incluirse en la clusula GROUP BY o como argumentos de una funcin SQL agregada. SELECT FROM IdFamilia, Sum(Stock) AS StockActual

Productos GROUP BY IdFamilia Una vez que GROUP BY ha combinado los registros, HAVING muestra cualquier registro agrupado por la clusula GROUP BY que satisfaga las condiciones de la clusula HAVING. HAVING es similar a WHERE, determina qu registros se seleccionan. Una vez que los registros se han agrupado utilizando GROUP BY, HAVING determina cuales de ellos se van a mostrar. SELECT FROM IdFamilia, Sum(Stock) AS StockActual Productos

GROUP BY IdFamilia HAVING StockActual > 100 AND NombreProducto Like BOS* AVG Calcula la media aritmtica de un conjunto de valores contenidos en un campo especificado de una consulta. Su sintaxis es la siguiente Avg(expr) En donde expr representa el campo que contiene los datos numricos para los que se desea calcular la media o una expresin que realiza un clculo utilizando los datos de dicho campo. La media calculada por Avg es la media aritmtica (la suma de los valores dividido por el nmero de valores). La funcin Avg no incluye ningn campo Null en el clculo. SELECT FROM WHERE Count Calcula el nmero de registros devueltos por una consulta. Su sintaxis es la siguiente Count(expr) En donde expr contiene el nombre del campo que desea contar. Los operandos de expr pueden incluir el nombre de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida por el usuario pero no otras de las funciones agregadas de SQL). Puede contar cualquier tipo de datos incluso texto. Aunque expr puede realizar un clculo sobre un campo, Count simplemente cuenta el nmero de registros sin tener en cuenta qu valores se almacenan en los registros. La funcin Count no cuenta los registros que tienen campos null a menos que expr sea el carcter comodn asterisco (*). Si utiliza un asterisco, Count calcula el nmero total de registros, incluyendo aquellos que contienen campos null. Count(*) es considerablemente ms rpida que Count(Campo). No se debe poner el asterisco entre dobles comillas ('*'). Avg(Gastos) AS Promedio Pedidos Gastos > 100

SELECT FROM

Count(*) AS Total Pedidos

Si expr identifica a mltiples campos, la funcin Count cuenta un registro slo si al menos uno de los campos no es Null. Si todos los campos especificados son Null, no se cuenta el registro. Hay que separar los nombres de los campos con ampersand (&). SELECT FROM Count(FechaEnvo & Transporte) AS Total Pedidos

Podemos hacer que el gestor cuente los datos diferentes de un determinado campo SELECT FROM Count(DISTINCT Localidad) AS Total Pedidos

Max, Min Devuelven el mnimo o el mximo de un conjunto de valores contenidos en un campo especifico de una consulta. Su sintaxis es: Min(expr) Max(expr) En donde expr es el campo sobre el que se desea realizar el clculo. Expr pueden incluir el nombre de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida por el usuario pero no otras de las funciones agregadas de SQL). SELECT FROM WHERE SELECT FROM WHERE Min(Gastos) AS ElMin Pedidos Pais = 'Espaa' Max(Gastos) AS ElMax Pedidos Pais = 'Espaa'

StDev, StDevP Devuelve estimaciones de la desviacin estndar para la poblacin (el total de los registros de la tabla) o una muestra de la poblacin representada (muestra aleatoria). Su sintaxis es: StDev(expr) StDevP(expr) En donde expr representa el nombre del campo que contiene los datos que desean evaluarse o una expresin que realiza un clculo utilizando los datos de dichos campos. Los operandos de expr pueden incluir el nombre de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida por el usuario pero no otras de las funciones agregadas de SQL). StDevP evala una poblacin, y StDev evala una muestra de la poblacin. Si la consulta contiene menos de dos registros (o ningn registro para StDevP), estas funciones devuelven un valor Null (el cual indica que la desviacin estndar no puede calcularse). SELECT FROM WHERE SELECT FROM WHERE Sum Devuelve la suma del conjunto de valores contenido en un campo especifico de una consulta. Su sintaxis es: Sum(expr) En donde expr representa el nombre del campo que contiene los datos que desean sumarse o una expresin que realiza un clculo utilizando los datos de dichos campos. Los operandos de expr pueden incluir el nombre de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida por el usuario pero no otras de las funciones agregadas de SQL). SELECT Sum(PrecioUnidad * Cantidad) AS Total StDev(Gastos) AS Desviacin Pedidos Pas = 'Espaa' StDevP(Gastos) AS Desviacin Pedidos Pas = 'Espaa'

FROM

DetallePedido

Var, VarP Devuelve una estimacin de la varianza de una poblacin (sobre el total de los registros) o una muestra de la poblacin (muestra aleatoria de registros) sobre los valores de un campo. Su sintaxis es: Var(expr) VarP(expr) VarP evala una poblacin, y Var evala una muestra de la poblacin. Expr el nombre del campo que contiene los datos que desean evaluarse o una expresin que realiza un clculo utilizando los datos de dichos campos. Los operandos de expr pueden incluir el nombre de un campo de una tabla, una constante o una funcin (la cual puede ser intrnseca o definida por el usuario pero no otras de las funciones agregadas de SQL) Si la consulta contiene menos de dos registros, Var y VarP devuelven Null (esto indica que la varianza no puede calcularse). Puede utilizar Var y VarP en una expresin de consulta o en una Instruccin SQL. SELECT FROM WHERE SELECT FROM WHERE Var(Gastos) AS Varianza Pedidos Pas = 'Espaa' VarP(Gastos) AS Varianza Pedidos Pas = 'Espaa'

COMPUTE de SQL-SERVER Esta clusula aade una fila en el conjunto de datos que se est recuperando, se utiliza para realizar clculos en campos numricos. COMPUTE acta siempre sobre un campo o expresin del conjunto de resultados y esta expresin debe figurar exactamente igual en la clusula SELECT y siempre se debe ordenar el resultado por la misma o al memos agrupar el resultado. Esta expresin no puede utilizar ningn ALIAS. SELECT FROM IdCliente, Count(IdPedido)

Pedidos GROUP BY IdPedido HAVING Count(IdPedido) > 20 COMPUTE Sum(Count(IdPedido)) SELECT IdPedido, (PrecioUnidad * Cantidad - Descuento) FROM [Detalles de Pedidos] ORDER BY IdPedido COMPUTE Sum((PrecioUnidad * Cantidad - Descuento)) // Calcula el Total BY IdPedido // Calcula el Subtotal

Null (SQL) De Wikipedia, la enciclopedia libre Saltar a: navegacin, bsqueda Null (nulo) es un marcador especial usado en el lenguaje de consulta estructurado (SQL) para indicar que no existe un valor dentro de una base de datos.

Introducido por el creador del modelo relacional de bases de datos E. F. Codd, su funcin es la de solventar el requisito de que los sistemas de gestin relacionales de base de datos (en ingls: Database management system, abreviado DBMS) verdaderos puedan representar informacin desconocida o no aplicable. Asimismo, Codd tambin introdujo el uso de la letra griega omega () en minscula para representar el Null en la teora de la teora de las bases de datos. NULL es tambin una palabra reservada en el lenguaje SQL para identificar el marcador especial Null. Null ha sido un foco de controversia y una fuente de debate debido a su asociacin a la lgica ternaria (en ingls: Three-Valued Logic, abreviado 3VL), a sus restricciones de uso en SQL y a la dificultad de su manejo en SQL. Aunque las funciones especiales y predicados sirven para manejar eficazmente el Nulls, la competencia opina que resolver este tipo de cuestiones aade complejidades y contradicciones innecesarias dentro del modelo relacional de bases de datos. Contenido [ocultar]

1 Historia 2 Lgica ternaria (Three-valued logic -3VL-)

3 Tipos de datos 4 Lenguaje de manipulacin de datos 5 Expresiones CASE 6 Revisin de las limitaciones 7 Extensiones de procedimientos 8 Sentencias JOIN 9 Concadenacin matemtica y de caracteres 10 Funciones agregadas 11 Agrupacin y clasificacin 12 Fuciones de tratamiento de Null 13 COALESCE 14 NULLIF 15 Vase tambin 16 Enlaces externos

[editar] Historia Null fue introducido por E. F. Codd como un mtodo de representacin de datos que faltan en el modelo relacional. Codd ms tarde reforz su llamamiento para que todos los RDBMS incluyeran la funcin null para indicar los datos que faltan en un doble artculo publicado en la revista ComputerWorld. Codd tambin introdujo la lgica ternaria, consistente en la veracidad de los valores True (verdadero), False (falso), y Desconocido (Unknown), los cuales estn estrechamente relacionados con el concepto de Null. El valor Desconocido verdadero es generado cuando Null es comparado con cualquier dato, o con otro Null. Codd indic en su libro The Relational Model for Database Management publicado en 1990, Version 2 que un solo mandato Null a travs del estndar SQL era inadecuado, y debera ser reemplazado por dos marcadores Null separados para indicar la razn de por qu los datos faltan. Estos dos tipos de marcadores Null son llamados comnmente Valores A y Valores I, representando datos que faltan pero aplicables y datos que faltan pero no aplicables, respectivamente. La recomendacin de Codd debera haber requerido una expansin del sistema lgico del SQL para acomodar el sistema lgico cuaternario. Debido a su adicional complejidad, la idea de los mltiples valores Null no ha logrado un reconocimiento general. [editar] Lgica ternaria (Three-valued logic -3VL-) Debido a que no pertenece a ningn dominio de datos, Null no est considerado propiamente un valor, pero realmente s que es un marcador que indica la ausencia de un valor. Debido a esto, las comparaciones con Null nunca resultan ciertas o falsas, pero si como un resultado lgico ternario, desconocidas (unknown). El resultado lgico de la siguiente expresin, la cual compara el valor 10 con Null, es Desconocido: 10 = NULL -- Resultados en Desconocido (Unknown) De todas formas, ciertas operaciones con Null pueden devolver valores si el valor Null no es relevante ante el resultado de la operacin. Es el caso del siguiente ejemplo, considerando que la declaracin OR es evaluada en forma de giro corto: TRUE OR NULL -- Resultados en Verdadero (True)

En este caso, el hecho de que el valor a la derecha de OR es desconocido es irrelevante, porque el resultado de la operacin debera ser Verdadera a pesar del valor de la derecha. SQL aplica resultados lgicos ternarios, luego las aplicaciones de SQL deben proporcionar unos valores lgicos ternarios especializados. Las reglas que gobiernan los valores lgicos ternarios en SQL se muestran en las siguientes tablas (p y q representan estados lgicos): p F al so Fa ls o Fa ls o Fa ls o p Desc p OR q Ver Desc onoci dade Falso onoci do ro do Desc Verd Verd Verd Verd onoci ader ader adero adero do o o Verd Desc Falso q Falso ader Falso onoci o do Desc Desc Verd Desc Desc onoci onoci ader onoci onoci do do do do o NOT p p

p AND Verd q ader o Verd Verd ader adero o q Falso Falso Desc Desc onoci onoci do do

Desc p = q Verd Verd ader Falso onoci Falso adero o do Verd Desc Verd Falso Verd adero Falso onoci ader adero do o Desc Desc onoci onoci Desc Verd do do onoci q Falso Falso adero do Desc Desc Desc Desc onoci onoci onoci onoci do do do do

Las comparaciones operarias bsicas en SQL resultan Desconocidas comparando cualquier cosa con Null, luego el estndar de SQL estipula clculos predicados cotejados especiales para las dos funciones especficas Null. El test ES NULL y NO ES NULL determina si el dato es, o no es, Null. [editar] Tipos de datos Null no est diseado como un nmero entero, caracter u otro tipo de dato especfico. Debido a esto, es a veces deseable convertir explcitamente Null en un tipo de dato especfico. Por ejemplo, si las funciones sobrecargadas son sostenidas por el SGBD (Sistema de Gestin de Base de Datos), SQL quizs no podra ser capaz de decidir la funcin correcta sin conocer los tipos de datos de todos los parmetros, incluidos aquellos para los cuales Null ha actuado. [editar] Lenguaje de manipulacin de datos Los valores lgicos ternarios de SQL se encuentran en el Lenguaje de Manipulacin de Datos (LMD) en comparaciones predicadas de afirmaciones LMD y dudas frecuentes. La proposicin WHERE (DONDE) propicia que la declaracin LMD acte slo en aquellas filas para las cuales los clculos de predicados evalan la Verdad. Las filas para las cuales estos clculos evalan si son Falsas o Desconocidas no derivan de declaraciones DML como INSERT, UPDATE o DELETE, y son desechados a partir de preguntas SELECT. Interpretando Desconocido y Falso como el mismo resultado lgico es un error comn encontrado cuando tratamos con Nulls. El siguiente ejemplo lo demuestra: SELECT * FROM t WHERE i = NULL;

El ejemplo arriba planteado siempre devuelve lgicamente ceros a las filas debido a que la comparacin entre la columna i con Null siempre devuelve un valor Desconocido, incluso para aquellas filas en las que i es Null. El resultado Desconocido causa la declaracin SELECT para desechar todas y cada una de las filas (De todas formas, en la prctica, las herramientas SQL recuperarn las filas utilizando la comparacin con Null). [editar] Expresiones CASE Las expresiones CASE de SQL funcionan conforme a las mismas reglas que las del DMS WHERE para Null. Debido a que puede ser evaluado como una serie de condiciones de comparacin de igualdad, una expresin de CASE simple no puede comprobar la existencia de Null directamente. Una comprobacin de la existencia de Null en una expresin CASE simple siempre resulta Desconocida, como a continuacin: SELECT CASE i WHEN NULL THEN 'Es Null' -- Esto nunca ser devuelto. WHEN 0 THEN 'Es Cero' -- Esto ser devuelto cuando i = 0 WHEN 1 THEN 'Es uno' -- Esto ser devuelto cuando i = 1 END FROM t; Como la expresin i = NULL evala a Desconocido sin importar el valor que la columna i contenga (incluso si contiene el Null), el resultado ' ES NULL ' nunca ser devuelto. Una expresin de CASE buscada tambin devuelve el primer valor para el cual el resultado de la comparacin predicada evala la Verdad, incluyendo comparaciones predicadas que usan el ES NULL Y NO ES NULL. El ejemplo siguiente muestra cmo usar una expresin CASE buscada para comprobar el Null: SELECT CASE WHEN i IS NULL THEN 'Es Null' -- Esto ser devuelto cuando i es NULL WHEN i = 0 THEN 'Cero' -- Esto ser devuelto i = 0 WHEN i = 1 THEN 'Uno' -- Esto ser devuelto i = 1 END FROM t; En la expresin CASE buscada, ' el Resultado Null ' es devuelta para todas las filas en las cuales i es Null. [editar] Revisin de las limitaciones El lugar primario en el cual la lgica ternaria SQL se entrecruza con la Lengua de Definicin de Datos SQL (DDL) es en forma de revisin de las limitaciones. Una revisin o comprobacin de las limitaciones colocada sobre una columna opera bajo una serie de reglas ligeramente diferentes de aquellas para la clusula DML WHERE. Mientras que una clusula DML WHERE debe evaluar la Verdad para una fila, una comprobacin no debe evaluar la Falsedad. Esto quiere decir que una revisin tendr xito si el resultado de la comprobacin es Verdadero o Desconocido. El ejemplo

siguiente muestra una tabla con una comprobacin que prohibir a cualquier valor de nmero entero ser insertado en la columna i, pero permitir a la Null ser insertada ya que el resultado de la comprobacin siempre evaluar si es Desconocido para la Null. CREATE TABLE t ( i INTEGER, CONSTRAINT ck_i CHECK ( i < 0 AND i = 0 AND i > 0 ) ); Con el objetivo de que una columna rechace Nulls, la coaccin NOT NULL puede ser aplicada, como abajo se muestra en el ejemplo. La coaccin NOT NULL es semnticamente equivalente a una comprobacin de las limitaciones con un predicado IS NOT NULL. CREATE TABLE t ( i INTEGER NOT NULL ); [editar] Extensiones de procedimientos SQL/PSM (SQL Mdulos Persistentes Almacenados) define extensiones procesales para SQL, como la declaracin IF. Sin embargo, las principales comercializaciones de SQL, histricamente han incluido sus extensiones procesales propias. Las extensiones procesales para la formacin de bucles y comparaciones funcionan bajo las reglas de comparacin Null, similares a las declaraciones DML e interrogaciones. El siguiente fragmento de cdigo, en formato estndar ISO SQL, demuestra el empleo del Null 3VL en una declaracin IF. IF i = NULL THEN SELECT 'Result ELSEIF NOT(i = NULL) SELECT 'Result ELSE SELECT 'Result is True' THEN is False' is Unknown';

La declaracin IF realiza acciones slo para aquellas comparaciones que evalan la Verdad. Para las declaraciones que evalan la Falsedad o Desconocimiento, la declaracin IF pasa el control de la clusula ELSEIF, y finalmente la clusula ELSE. El resultado de ste cdigo, siempre ser el mensaje 'Resultado es Desconocido' ya que las comparaciones con Null siempre evalan el Desconocimiento. [editar] Sentencias JOIN La sentencia JOIN en SQL permite la combinacin de registros de dos o ms tablas dentro de una misma base de datos relacional. En SQL existen tres tipos de JOIN: interno, externo, y cruzado. Las sentencias JOIN externas (Outer Joins), incluyendo las de tabla izquierda, derecha y de combinacin completa, automticamente producen Nulls como marcadores (placeholders) de para los valores que faltan en tablas relacionadas. Para combinaciones externas de tabla izquierda, por ejemplo, los Nulls son producidos en lugar de las filas ausentes de la tabla apareciendo en el lado derecho del operador JOIN externo de tabla izquierda. El siguiente ejemplo utiliza dos tablas para demostrar que la produccin del marcador Null en la combinacin externa izquierda. La primera tabla (Empleado) contiene los nmeros y nombres del empleado ID, mientras la segunda tabla (Nmero de telfono) contiene nmeros de telfono relacionados con el empleado ID, como se muestra abajo.

Empleado Nmero de telfono ID Apellido Nombre ID Nmero 1 Izquierdo Roberto 1 555-2323 2 Ambrosio Alberto 3 555-9876 3 Alfonso Katia 4 Barbadillo Guillermo La siguiente muestra SQL desarrolla una combinacin externa de tabla izquierda entre las dos tablas anteriores. SELECT e.ID, e.Apellido, e.Nombre, pn.Nmero FROM Empleado e LEFT OUTER JOIN Nmero de telfono pn ON e.ID = pn.ID; El resultado generado en esta serie de cuestiones demuestra cmo SQL usa el Null como un marcador para valores que faltan en la parte derecha de la tabla (Nmeros de telfono), como se muestra a continuacin: Resultado de la encuesta ID Apellido Nombre Nmero 1 Izquierdo Roberto 555-2323 2 Ambrosio Alberto NULL 3 Alfonso Katia 555-9876 4 Barbadillo Guillermo NULL Las combinaciones internas (Inner Joins) y las cruzadas (Cross Joins), tambin estn disponibles en el estndar SQL, y no generan marcadores Null para valores ausentes en tablas relacionadas. Es necesario tener cuidado a la hora de utilizar columnas en las que pueda operar Null en criterios de unificacin de SQL. Como un Null no es igual a ninguna otro Null, los Nulls que se encuentren en una columna de una tabla no se unirn a Nulls de columnas relacionadas de otra tabla que usa los operadores de comparacin de igualdad estndar. La funcin SQL COALESCE o expresiones CASE pueden ser usadas para "simular" una igualdad Null en criterios de unificacin, y los predicados ES NULO Y NO ES NULL pueden ser utilizados en los criterios de unificacin tambin. El predicado siguiente prueba para la igualdad de los valores A y B y trata a Null como si fuera igual. Se requiere el operador IFNULL ya que A = B devuelve un valor Null si al menos uno de los valores (A o B) es Null y NULL O FALSO es Nulo en s mismo. IFNULL( A = B, FALSO ) OR ( A IS NULL AND B IS NULL ) [editar] Concadenacin matemtica y de caracteres

Como Null no es un valor de datos, pero un marcador para un valor desconocido, usando operadores matemticos sobre Null resulta un valor desconocido, que es representado por Null. En el ejemplo siguiente, multiplicando 10 por Null resulta Null: 10 * NULL -- Resultado es NULL Esto puede conducir a resultados inesperados. Por ejemplo, cuando una tentativa es hecha para dividir Null entre cero, las plataformas pueden devolver Null en vez de lanzar una esperado "excepcin de datos - la divisin entre cero". Aunque este comportamiento no sea definido por la estndar SQL ISO muchos productos comercializados DBMS tratan esta operacin de modo similar. Por ejemplo, las plataformas Oracle, PostgreSQL, MySQL Server, y Microsoft SQL Server devuelven el resultado Null para la operacin: NULL / 0 La serie de operaciones concadenadas, que son comunes en SQL, tambin resultan Null cuando uno de los operndos es Null. El siguiente ejemplo demuestra el resultado Null devuelto por el uso de Null con el SQL || operador de una serie concadenada. 'Tortilla' || NULL || 'Patatas - Resultado es NULL Esto no es verdadero para todas las puestas en prctica de base de datos. En Oracle RDBMS por ejemplo NULL y serie vaca son consideradas la misma cosa y por lo tanto Tortilla la NULL || || Patata resulta Tortilla Patata. [editar] Funciones agregadas SQL define las funciones agregadas para simplificar clculos agregados de datos del servidor. Casi todas las funciones agregadas realizan un paso de eliminacin Null, de modo que los valores Null no sean incluidos en el resultado final del clculo. Esta eliminacin implcita Null, sin embargo, puede influir en los resultados de funciones agregadas. La tabla ejemplificada a continuacin deriva resultados diferentes siendo devueltos a cada columna cuando la funcin agregada SQL AVG (media) es aplicada: Tabla i j 150 150 200 200 350 350 NULL 0 La funcin agregada SQL AVG devuelve 233 cuando se aplica a la columna i, pero vuelve 175 cuando es aplicado a la columna j. El paso de eliminacin de la funcin agregada Null explica la diferencia en estos resultados. La nica funcin agregada que no elimina implcitamente la Null es la funcin COUNT. [editar] Agrupacin y clasificacin

Como SQL:2003 define todos los marcadores Null como desiguales entre s, requirieron una definicin especial para agrupar las Null en la realizacin de ciertas operaciones. SQL define "cualquiera de los dos valores que sean iguales el uno al otro, o cualquier pareja de Nulls", como "no distinto". Esta definicin de no distinto permite a SQL agrupar y clasificar los Nulls cuando la clusula GROUP BY (y otras palabras clave que realizan la agrupacin) es usada. Otras operaciones SQL, clusulas, y palabras clave usan "no distinto" en su tratamiento de Nulls. Estos incluyen lo siguiente:

La clusula de clasificacin PARTITION BY y funciones de enventanado (windowing) como ROW_NUMBER. UNION, INTERSECT y el operador EXCEPT, que tratan los NULLs igual para las determinaciones de comparacin/eliminacin en filas. La palabra clave DISTINCT es usada en preguntas SELECT. Coacciones nicas sobre columnas en las que pueda encontrarse la funcin Null, que permiten slo a un valor solo Nulo ser almacenado en la columna.

El estndar SQL no define explcitamente por defecto la clase de orden para los Null. En cambio, sobre sistemas conformados, los Nulls pueden ser clasificados antes o despus de todos los valores de datos mediandte el uso de las clusulas NULLS FIRST o NULLS LAST de la lista ORDER BY, respectivamente. No todos los vendedores de DBMS ponen en prctica esta funcionalidad pese a todo. Los vendedores que no ponen en prctica esta funcionalidad pueden especificar tratamientos diferentes para la clasificacin de Null en el DBMS. [editar] Fuciones de tratamiento de Null SQL define dos funciones para manejar explcitamente la Null: COALESCE y NULLIF. Ambas funciones son abreviaturas para expresiones CASE buscadas. [editar] COALESCE La funcin COALESCE acepta una lista de parmetros, devolviendo el primer valor no Null de la lista: COALESCE(value1, value2, value3, ...) COALESCE est definida como la siguiente expresin SQL CASE: CASE WHEN value1 IS NOT NULL THEN valor1 WHEN value2 IS NOT NULL THEN valor2 WHEN value3 IS NOT NULL THEN valor3 ... END Algn DBMSs SQL pone en prctica funciones especficas de vendedor similares para COALESCE. Algunos sistemas ponen en prctica una funcin de ISNULL, u otras funciones parecidas que son funcionalmente similares a COALESCE. [editar] NULLIF

La funcin de NULLIF acepta dos parmetros. Si el primer parmetro es igual al segundo, NULLIF devuelve Null. De otra manera, el valor del primer parmetro es devuelto. NULLIF(valor1, valor2) Por lo tanto, NULLIF es una abreviatura de de la siguiente expresin CASE: CASE WHEN valor1 = valor2 THEN NULL ELSE valor1 END

"null" significa "dato desconocido" o "valor inexistente". No es lo mismo que un valor "0", una cadena vaca o una cadena literal "null". A veces, puede desconocerse o no existir el dato correspondiente a algn campo de un registro. En estos casos decimos que el campo puede contener valores nulos. Por ejemplo, en nuestra tabla de libros, podemos tener valores nulos en el campo "precio" porque es posible que para algunos libros no le hayamos establecido el precio para la venta. En contraposicin, tenemos campos que no pueden estar vacos jams. Veamos un ejemplo. Tenemos nuestra tabla "libros". El campo "titulo" no debera estar vaco nunca, igualmente el campo "autor". Para ello, al crear la tabla, debemos especificar que dichos campos no admitan valores nulos: create table libros( titulo varchar(30) not null, autor varchar(20) not null, editorial varchar(15) null, precio float ); Para especificar que un campo no admita valores nulos, debemos colocar "not null" luego de la definicin del campo. En el ejemplo anterior, los campos "editorial" y "precio" si admiten valores nulos. Cuando colocamos "null" estamos diciendo que admite valores nulos (caso del campo "editorial"); por defecto, es decir, si no lo aclaramos, los campos permiten valores nulos (caso del campo "precio"). Si ingresamos los datos de un libro, para el cual an no hemos definido el precio podemos colocar "null" para mostrar que no tiene precio: insert into libros (titulo,autor,editorial,precio) values('El aleph','Borges','Emece',null);

Note que el valor "null" no es una cadena de caracteres, no se coloca entre comillas. Entonces, si un campo acepta valores nulos, podemos ingresar "null" cuando no conocemos el valor. Tambin podemos colocar "null" en el campo "editorial" si desconocemos el nombre de la editorial a la cual pertenece el libro que vamos a ingresar: insert into libros (titulo,autor,editorial,precio) values('Alicia en el pais','Lewis Carroll',null,25); Si intentamos ingresar el valor "null" en campos que no admiten valores nulos (como "titulo" o "autor"), SQL Server no lo permite, muestra un mensaje y la insercin no se realiza; por ejemplo: insert into libros (titulo,autor,editorial,precio) values(null,'Borges','Siglo XXI',25); Para ver cules campos admiten valores nulos y cules no, podemos emplear el procedimiento almacenado "sp_columns" junto al nombre de la tabla. Nos muestra mucha informacin, en la columna "IS_NULLABLE" vemos que muestra "NO" en los campos que no permiten valores nulos y "YES" en los campos que si los permiten. Para recuperar los registros que contengan el valor "null" en algn campo, no podemos utilizar los operadores relacionales vistos anteriormente: = (igual) y <> (distinto); debemos utilizar los operadores "is null" (es igual a null) y "is not null" (no es null): select * from libros where precio is null; La sentencia anterior tendr una salida diferente a la siguiente: select * from libros where precio=0; Con la primera sentencia veremos los libros cuyo precio es igual a "null" (desconocido); con la segunda, los libros cuyo precio es 0. Igualmente para campos de tipo cadena, las siguientes sentencias "select" no retornan los mismos registros: select * from libros where editorial is null; select * from libros where editorial=''; Con la primera sentencia veremos los libros cuya editorial es igual a "null", con la segunda, los libros cuya editorial guarda una cadena vaca. Entonces, para que un campo no permita valores nulos debemos especificarlo luego de definir el campo, agregando "not null". Por defecto, los campos permiten valores nulos, pero podemos especificarlo igualmente agregando "null".

Sub consultas (Consultas Anidadas)

Una de las caractersticas ms tiles dentro del lenguaje SQL, es la posibilidad de anidar consultas para simplificar la sentencia o poder realizar operaciones que deotra manera seran imposibles o requeriran de la creacin de tablas temporalesexplicitas.Las consultas anidadas funcionan para cualquier motivo igual que una tabla. Aqu se da el nombre tabla2 al resultado.

SELECT * FROM (SELECT * FROM tabla1) as tabla2;

Es necesario darle un nombre cada subconsulta para que puedaidentificarlo y referenciarlo inequvocamente Una subconsulta es una instruccin SELECT anidada dentro de una instruccin SELECT, SELECT...INTO, INSERT...INTO, DELETE, o UPDATE o dentro de otra subconsulta. Puede utilizar tres formas de sintaxis para crear una subconsulta: comparacin [ANY | ALL | SOME] (instruccin sql) expresin [NOT] IN (instruccin sql) [NOT] EXISTS (instruccin sql) En donde: comparacin expresin instruccin SQL Es una expresin y un operador de comparacin que compara la expresin con el resultado de la subconsulta. Es una expresin por la que se busca el conjunto resultante de la subconsulta. Es una instruccin SELECT, que sigue el mismo formato y reglas que cualquier otra instruccin SELECT. Debe ir entre parntesis.

Se puede utilizar una subconsulta en lugar de una expresin en la lista de campos de una instruccin SELECT o en una clusula WHERE o HAVING. En una subconsulta, se utiliza una instruccin SELECT para proporcionar un conjunto de uno o ms valores especificados para evaluar en la expresin de la clusula WHERE o HAVING. Se puede utilizar el predicado ANY o SOME, los cuales son sinnimos, para recuperar registros de la consulta principal, que satisfagan la comparacin con

cualquier otro registro recuperado en la subconsulta. El ejemplo siguiente devuelve todos los productos cuyo precio unitario es mayor que el de cualquier producto vendido con un descuento igual o mayor al 25 por ciento: SELECT * FROM Productos WHERE PrecioUnidad ANY ( SELECT PrecioUnidad FROM DetallePedido WHERE Descuento = 0 .25 ) El predicado ALL se utiliza para recuperar nicamente aquellos registros de la consulta principal que satisfacen la comparacin con todos los registros recuperados en la subconsulta. Si se cambia ANY por ALL en el ejemplo anterior, la consulta devolver nicamente aquellos productos cuyo precio unitario sea mayor que el de todos los productos vendidos con un descuento igual o mayor al 25 por ciento. Esto es mucho ms restrictivo. El predicado IN se emplea para recuperar nicamente aquellos registros de la consulta principal para los que algunos registros de la subconsulta contienen un valor igual. El ejemplo siguiente devuelve todos los productos vendidos con un descuento igual o mayor al 25 por ciento: SELECT * FROM Productos WHERE IDProducto IN ( SELECT IDProducto FROM DetallePedido WHERE Descuento = 0.25 ) Inversamente se puede utilizar NOT IN para recuperar nicamente aquellos registros de la consulta principal para los que no hay ningn registro de la subconsulta que contenga un valor igual.

El predicado EXISTS (con la palabra reservada NOT opcional) se utiliza en comparaciones de verdad/falso para determinar si la subconsulta devuelve algn registro. Supongamos que deseamos recuperar todos aquellos clientes que hayan realizado al menos un pedido: SELECT FROM Clientes.Compaa, Clientes.Telfono

Clientes WHERE EXISTS ( SELECT FROM Pedidos WHERE Pedidos.IdPedido = Clientes.IdCliente ) Esta consulta es equivalente a esta otra: SELECT FROM WHERE Clientes.Compaa, Clientes.Telfono Clientes IdClientes IN ( SELECT Pedidos.IdCliente FROM Pedidos )

Se puede utilizar tambin alias del nombre de la tabla en una subconsulta para referirse a tablas listadas en la clusula FROM fuera de la subconsulta. El ejemplo siguiente devuelve los nombres de los empleados cuyo salario es igual o mayor que el salario medio de todos los empleados con el mismo ttulo. A la tabla Empleados se le ha dado el alias T1: SELECT FROM WHERE Apellido, Nombre, Titulo, Salario Empleados AS T1 Salario = ( SELECT Avg(Salario) FROM

Empleados WHERE T1.Titulo = Empleados.Titulo ) ORDER BY Titulo En el ejemplo anterior, la palabra reservada AS es opcional. SELECT FROM WHERE Apellidos, Nombre, Cargo, Salario Empleados

Cargo LIKE 'Agente Ven*' AND Salario ALL ( SELECT Salario FROM Empleados WHERE Cargo LIKE '*Jefe*' OR Cargo LIKE '*Director*' ) (Obtiene una lista con el nombre, cargo y salario de todos los agentes de ventas cuyo salario es mayor que el de todos los jefes y directores.) SELECT DISTINCT NombreProducto, Precio_Unidad FROM Productos WHERE PrecioUnidad = ( SELECT PrecioUnidad FROM Productos WHERE NombreProducto = 'Almbar anisado' ) (Obtiene una lista con el nombre y el precio unitario de todos los productos con el mismo precio que el almbar anisado.) SELECT DISTINCT NombreContacto, NombreCompania, CargoContacto, Telefono FROM Clientes WHERE

IdCliente IN ( SELECT DISTINCT IdCliente FROM Pedidos WHERE FechaPedido <#07/01/1993# ) (Obtiene una lista de las compaas y los contactos de todos los clientes que han realizado un pedido en el segundo trimestre de 1993.) SELECT Nombre, Apellidos FROM Empleados AS E WHERE EXISTS ( SELECT * FROM Pedidos AS O WHERE O.IdEmpleado = E.IdEmpleado ) (Selecciona el nombre de todos los empleados que han reservado al menos un pedido.) SELECT DISTINCT Pedidos.Id_Producto, Pedidos.Cantidad, ( SELECT Productos.Nombre FROM Productos WHERE Productos.IdProducto = Pedidos.IdProducto ) AS ElProducto FROM Pedidos WHERE Pedidos.Cantidad = 150 ORDER BY Pedidos.Id_Producto (Recupera el Cdigo del Producto y la Cantidad pedida de la tabla pedidos, extrayendo el nombre del producto de la tabla de productos.) SELECT NumVuelo, Plazas FROM Vuelos WHERE Origen = 'Madrid' AND Exists ( SELECT T1.NumVuelo FROM Vuelos AS T1 WHERE T1.PlazasLibres > 0 AND T1.NumVuelo=Vuelos.NumVuelo) (Recupera nmeros de vuelo y capacidades de aquellos vuelos con destino Madrid y plazas libres

Supongamos ahora que tenemos una tabla con los identificadores de todos nuestros productos y el stock de cada uno de ellos. En otra tabla se encuentran todos los pedidos que tenemos pendientes de servir. Se trata de averiguar que productos no se podemos servir por falta de stock. SELECT FROM PedidosPendientes.Nombre

PedidosPendientes GROUP BY PedidosPendientes.Nombre HAVING SUM(PedidosPendientes.Cantidad < ( SELECT Productos.Stock FROM Productos WHERE Productos.IdProducto = PedidosPendientes.IdProducto ) ) Supongamos que en nuestra tabla de empleados deseamos buscar todas las mujeres cuya edad sea mayor a la de cualquier hombre: SELECT FROM WHERE Empleados.Nombre Empleados Sexo = 'M' AND Edad > ANY (SELECT Empleados.Edad FROM Empleados WHERE Sexo ='H')

lo que sera lo mismo: SELECT FROM WHERE Empleados.Nombre Empleados Sexo = 'M' AND Edad > (SELECT Max( Empleados.Edad )FROM Empleados WHERE Sexo ='H')

La siguiente tabla muestra algn ejemplo del operador ANY y ALL Valor 1 3 Operador > ANY Valor 2 (2,5,7) Resultado Cierto

3 3 3 3

= ANY = ANY > ALL < ALL

(2,5,7) (2,3,5,7) (2,5,7) (5,6,7)

Falso Cierto Falso Falso

El operacion =ANY es equivalente al operador IN, ambos devuelven el mismo resultado. Para concluir este apartado comentar que: la clusula EXISTS se puede emplear para generar la interseccin entre dos consultas y, por tanto, la clusula NOT EXISTS para generar la diferencia entre consultas.

Uno de los temas que ms cuesta a los que empiezan a aprender SQL son las consultas en las que se recogen diferentes tipos de datos de una mltiples tablas. Este artculo es una introduccin a como definir consultas de este tipo en PostgreSQL. Unos conocimientos bsicos de normalizacin de datos y un poco de lgebra relacional no vienen mal para entender mejor algunos de los trminos que vamos a usar en este artculo. La normalizacin de datos es tema para otro artculo, pero en este veremos brevemente algunos conceptos de lgebra relacional que nos pueden ayudar a entender mejor el tema que estamos tratando. El lgebra relacional es un tipo de lgebra con una serie de operadores que trabajan sobre una varias relaciones para obtener una relacin resultado. Es la base indispensable para poder escribir buenas consultas en SQL. Las operaciones ms importantes disponibles en lgebra relacional son:

Las operaciones de conjunto aplicadas a relaciones: unin(), interseccin() y diferencia(-)

Operaciones que eliminan una parte de las relaciones: seleccin() y proyeccin()

Operaciones que combinan las tuplas de dos relaciones: producto cartesiano(x), combinacion natural (><) y theta

Operacin que cambia el nombre de los atributos relacin: renombre()

A continuacin vamos a dar una breve introduccin sobre estas operaciones: Unin [RS] La unin de R y S es el conjunto de elementos que existen en R, en S, en las dos. Un elemento que existe tanto en R como en S aparece solamente una vez en la unin. En el lenguaje SQL este tipo de operacin se puede realizar con la clausula UNION Interseccin [RS] La interseccin de R y S es el conjunto de elementos que existen en R y en S. En el lenguaje SQL este tipo de operacin se puede realizar con la clausula INTERSECT Diferencia [R-S] La diferencia de R y S es el conjunto de elementos que existen en R pero no en S. R-S es diferente a S-R, S-R seria el conjunto de elementos que existen en S pero no en R. En el lenguaje SQL este tipo de operacin se puede realizar con la clausula EXCEPT Seleccin [c(R)]

Esta operacin aplicada a una relacion R, produce una nueva relacin con un subconjunto de tuplas de R. Este subconjunto de tuplas satisface y cumple cierta condicin(c) Proyeccin [a1,a2,...,an(R)] Esta operacin aplicada a una relacin R, produce una nueva relacin con solamente los atributos(columnas) especificados por a1,a2,...,an Producto cartesiano [RxS] El producto cartesiano de dos relaciones R y S es la relacin que se obtiene de la combinacin de todas las tuplas de R con todas las tuplas de S. Las tuplas de la relacin que se obtiene estn formadas por todos los atributos de R seguidos de todos los atributos de S. En el lenguaje SQL este tipo de operacin se puede realizar con la clusula CROSS JOIN separando las relaciones usadas en el producto con comas, en el FROM de la sentencia SQL. Combinaciones Por medio del operador combinacin (JOIN) podemos combinar dos relaciones segun una condicin para obtener tuplas compuestas por atributos de las dos relaciones combinadas. En el lenguaje SQL existen diferentes maneras de combinar dos relaciones. A continuacin teneis un resumen de las existentes en PostgreSQL:

Combinaciones internas (R INNER JOIN S): Un INNER JOIN entre dos relaciones R y S, es el resultado que se obtiene despues de aplicar al producto cartesiano de las dos relaciones R y S, una condicin para acotar dicho producto. Existen un par de casos especiales:

De equivalencia (Equi-join): Es un caso particular de INNER JOIN en el que la condicion que acota el resultado es una comparacin de igualdad.

R NATURAL JOIN S: Es un caso especial de equi-join en el que en el caso de existir columnas con el mismo nombre en las relaciones que se combinan, solo se incluir una de ellas en el resultado de la combinacin.

Combinaciones externas (OUTER JOINS): Un OUTER JOIN entre dos relaciones R y S contiene todas las tuplas que un INNER JOIN devolveria, ms una serie de tuplas que no tienen atributos en comn en las dos relaciones. Los diferentes tipos son:
o

R LEFT OUTER JOIN S: Un LEFT OUTER JOIN entre dos relaciones R y S, retorna todas las tuplas de la combinacin que tengan un atributo comn, ms todas las tuplas de la relacin de la izquierda (R) que no tengan un equivalente en la relacin de la derecha (S).

R RIGHT OUTER JOIN S: Un RIGHT OUTER JOIN entre dos relaciones R y S, retorna todas las tuplas de la combinacin que tengan un atributo comn, ms todas las tuplas de la relacin de la derecha (S) que no tengan un equivalente en la relacin de la izquierda (R).

R FULL OUTER JOIN S: Un FULL OUTER JOIN entre dos relaciones R y S, retorna todas las tuplas de la combinacin que tengan un atributo comn, ms todas las tuplas de la relacin de la izquierda (R) que no tenga un equivalente en la relacin de la derecha (S) y todas las tuplas de la relacin de la derecha (S) que no tenga un equivalente en la relacin de la izquierda (R).

Renombre [a/b(R)]

Esta operacin aplicada a una relacin R, produce una nueva relacin identica a R en donde el atributo 'b' ha sido renombrado a 'a'. El uso combinado de todas estas operaciones aplicado a nuestras relaciones dar lugar a consultas ms menos complejas. Utilizando los operadores definidos en algebra relacional, podemos definir de manera grfica (rboles) lineal la representacin algebraica de nuestra consulta. En consultas muy complicadas es lo que se deberia de hacer antes de empezar a escribir el codigo SQL, pero este es un tema para otro artculo. Ejemplos prcticos Nada mejor que unos ejemplos bsicos para ver como se aplica la teoria que hemos visto. Lo primero que vamos a hacer es definir un par de tablas que utilizaremos en nuestros ejemplos: postgres=# SELECT * FROM relacion_r; a | b | c ---+---+--1 | 2 | 3 4 | 5 | 6 (2 rows) postgres=# SELECT * FROM relacion_s; c | d | e ---+---+--4 | 5 | 6 7 | 8 | 9 (2 rows) En nuestro primer ejemplo realizamos una unin de las dos relaciones, el resultado obtenido seria: postgres=# SELECT * FROM relacion_r UNION SELECT * FROM relacion_s; a | b | c ---+---+--4 | 5 | 6

1 | 2 | 3 7 | 8 | 9 (3 rows) A continuacin realizamos una interseccin entre las dos relaciones: postgres=# SELECT * FROM relacion_r INTERSECT SELECT * FROM relacion_s; a | b | c ---+---+--4 | 5 | 6 (1 row) La diferencia entre estas dos relaciones daria el siguiente resultado. Como podeis ver, y por definicin, no es lo mismo la diferencia entre relacion_r y relacion_s, que entre relacion_s y relacion_r postgres=# SELECT * FROM relacion_r EXCEPT SELECT * FROM relacion_s; a | b | c ---+---+--1 | 2 | 3 (1 row) postgres=# SELECT * FROM relacion_s EXCEPT SELECT * FROM relacion_r; c | d | e ---+---+--7 | 8 | 9 (1 row) Vamos a definir una nueva fila (3,4,5) en la tabla relacion_s para ver unos ejemplos de como combinar estas dos relaciones mediante JOINs. postgres=# SELECT * FROM relacion_r; a | b | c ---+---+--1 | 2 | 3 4 | 5 | 6 (2 rows) postgres=# SELECT * FROM relacion_s; c | d | e ---+---+---

4 7 3 (3

| 5 | 6 | 8 | 9 | 4 | 5 rows)

La manera ms simple de combinar estas dos relaciones es realizar el producto cartesiano de ambas. Esto se puede realizar de dos maneras, bien definiendo las dos relaciones separadas por comas despues del FROM. postgres=# SELECT * FROM relacion_r,relacion_s; a | b | c | c | d | e ---+---+---+---+---+--1 | 2 | 3 | 4 | 5 | 6 1 | 2 | 3 | 7 | 8 | 9 1 | 2 | 3 | 3 | 4 | 5 4 | 5 | 6 | 4 | 5 | 6 4 | 5 | 6 | 7 | 8 | 9 4 | 5 | 6 | 3 | 4 | 5 (6 rows) O utilizando la clusula CROSS JOIN entre las dos relaciones. postgres=# SELECT * FROM relacion_r CROSS JOIN relacion_s; a | b | c | c | d | e ---+---+---+---+---+--1 | 2 | 3 | 4 | 5 | 6 1 | 2 | 3 | 7 | 8 | 9 1 | 2 | 3 | 3 | 4 | 5 4 | 5 | 6 | 4 | 5 | 6 4 | 5 | 6 | 7 | 8 | 9 4 | 5 | 6 | 3 | 4 | 5 (6 rows) En realidad un CROSS JOIN es el equivalente a un INNER JOIN ON (true). Esto porque el INNER JOIN es por definicin un producto cartesiano al que se le aplica una condicin para acotar el resultado. En este caso particular la condicin siempre se cumple para todas las tuplas al utilizar el valor TRUE, con lo que obtendremos todas las tuplas del producto cartesiano. postgres=# SELECT * FROM relacion_r INNER JOIN relacion_s ON (true); a | b | c | c | d | e ---+---+---+---+---+---

1 1 1 4 4 4 (6

| 2 | | 2 | | 2 | | 5 | | 5 | | 5 | rows)

3 3 3 6 6 6

| | | | | |

4 7 3 4 7 3

| | | | | |

5 8 4 5 8 4

| | | | | |

6 9 5 6 9 5

A continuacin podeis ver como definir un INNER JOIN con la condicin definida dentro de ON(). Este ejemplo es un Equi-join al utilizarse una comparacin de igualdad en la condicin. postgres=# SELECT * FROM relacion_r AS r INNER JOIN relacion_s AS s ON (r.c = s.c); a | b | c | c | d | e ---+---+---+---+---+--1 | 2 | 3 | 3 | 4 | 5 (1 rows) El mismo resultado obtenido con la clausula INNER JOIN se podria haber conseguido obteniendo el producto cartesiano de las dos relaciones y aplicando una condicin con WHERE (definicion de INNER JOIN). postgres=# SELECT * FROM relacion_r AS r, relacion_s AS s WHERE r.c = s.c; a | b | c | c | d | e ---+---+---+---+---+--1 | 2 | 3 | 3 | 4 | 5 (1 rows) postgres=# SELECT * FROM relacion_r as r CROSS JOIN relacion_s as s WHERE r.c = s.c; a | b | c | c | d | e ---+---+---+---+---+--1 | 2 | 3 | 3 | 4 | 5 (1 row) Un NATURAL JOIN retorna el mismo resultado que un equi-join, pero sin repetir las columnas comunes. postgres=# SELECT * from relacion_r natural join relacion_s; c | a | b | d | e ---+---+---+---+---

3 | 1 | 2 | 4 | 5 postgres=# SELECT a,b,c,d,e from relacion_r natural join relacion_s; a | b | c | d | e ---+---+---+---+--1 | 2 | 3 | 4 | 5 (1 row) Como podeis ver en lo que llevamos de artculo, existen diferentes maneras de obtener un mismo resultado utilizando diferentes tipos de consultas. Teniendo los conceptos claros y con prctica, os aseguro que todos estos tipos de consultas os saldrn de forma natural despues de un tiempo. A continuacin vamos a ver las combinaciones de tipo OUTER JOIN. En PostgreSQL el uso de la palabra OUTER es opcional, a mi me gusta utilizarla aunque no se necesite. La primera es un LEFT OUTER JOIN. postgres=# SELECT * FROM relacion_r AS r LEFT OUTER JOIN relacion_s AS s ON (r.c = s.c); a | b | c | c | d | e ---+---+---+---+---+--1 | 2 | 3 | 3 | 4 | 5 4 | 5 | 6 | | | (2 rows) Seguido de un RIGHT OUTER JOIN: postgres=# SELECT * FROM relacion_r AS r RIGHT OUTER JOIN relacion_s AS s ON (r.c = s.c); a | b | c | c | d | e ---+---+---+---+---+--1 | 2 | 3 | 3 | 4 | 5 | | | 4 | 5 | 6 | | | 7 | 8 | 9 (3 rows) Y para terminar un FULL OUTER JOIN:

postgres=# SELECT * FROM relacion_r AS r FULL OUTER JOIN relacion_s AS s ON (r.c = s.c); a | b | c | c | d | e ---+---+---+---+---+--1 | 2 | 3 | 3 | 4 | 5 | | | 4 | 5 | 6 4 | 5 | 6 | | | | | | 7 | 8 | 9 (4 rows) Un ejemplo casi real Los ejemplos que hemos visto hasta ahora, nos han mostrado la sintaxis bsica de las operaciones que se pueden utilizar para obtener resultados con datos de mltiples relaciones. En la vida real nos encontraremos con casos muchos ms complicados en los que tendremos que combinar todas estas operaciones junto con el resto de operadores y clusulas SQL disponibles. En casos complicados es importante pensar antes de empezar a escribir nuestra consulta SQL. A continuacin vamos a ver un ejemplo un poco ms complicado para ver como podemos desglosar y resolver la consulta que necesitamos para obtener el resultado deseado. Utilizaremos unas tablas creadas nicamente para este ejemplo y no representativas de un sistema real. Tenemos una tabla principal llamada 'PC', con diferentes columnas conteniendo cadenas de identificacin de los diferentes componentes usados para el ensamblado de diferentes modelos de PCs. Las columnas vacias de la tabla 'PC' significan componentes no presentes en dichos modelos. El resto de tablas contienen informacion adicional sobre los diferentes componentes usados para construir un PC. postgres=# SELECT * FROM pc; pcid | memoria | cpu | disco | tgrafica | precio ------+---------+---------+-----------+-----------+-------1 | mem0001 | cpu0001 | disco0001 | ati001 | 1000 2 | mem0001 | cpu0001 | disco0002 | ati001 | 1100 3 | mem0002 | cpu0002 | disco0003 | nvidia001 | 1400 4 | mem0004 | cpu0003 | disco0004 | nvidia001 | 1600

5 | 6 | (6 rows)

| cpu0001 | disco0001 | ati001 | | | ati001

| |

900 400

postgres=# SELECT * FROM cpu ; cpu_id | cpu_fabricante | cpu_tipo ---------+----------------+-----------cpu0001 | intel | Core2 duo cpu0002 | intel | Core2 Quad cpu0003 | amd | Athlon X2 (3 rows) postgres=# SELECT * FROM memoria ; mem_id | mem_capacidad | mem_tipo ---------+---------------+-----------mem0001 | 1024 | DDR SDRAM mem0002 | 1024 | DDR2 SDRAM mem0003 | 1024 | DDR3 SDRAM mem0004 | 2048 | DDR3 SDRAM (4 rows) postgres=# SELECT * FROM disco ; disco_id | disco_fabricante | disco_capacidad -----------+------------------+----------------disco0001 | seagate | 350 disco0002 | seagate | 500 disco0003 | seagate | 1024 disco0004 | samsung | 500 (4 rows) postgres=# SELECT * FROM tgrafica ; tgraf_id | tgraf_fabricante -----------+-----------------ati001 | ati nvidia001 | nvidia Utilizando estas tablas vamos a realizar varias consultas: Consulta 1 Obtener una relacin de solo los modelos de PC 'completos' a la venta. Queremos toda la informacin disponible sobre los componentes que lo forman. Ordenar el resultado de mayor a menor precio.

Sabemos que al tener que coger datos de diferentes tablas, necesitaremos algun tipo de clausula JOIN. En esta consulta nos piden solamente, PCs completos, con todos sus componentes. Por ello descartamos todas las combinaciones de tipo OUTER JOIN y utilizamos INNER JOIN para obtener solamente las tuplas con atributos en todas las relaciones combinadas. Cada PC tiene 4 componentes y la informacin de cada componente se encuentra en una tabla separada. Con estos datos sabemos que tendremos que realizar 4 INNER JOIN entre todas las tablas involucradas en la consulta. Vamos a empezar a escribir la consulta SQL. Primero realizamos los INNER JOIN y declaramos las condiciones que acotarn el resultado. Tendremos que emparejar los atributos de componentes presentes en la tabla 'PC' con los correspondientes atributos en el resto de tablas de componentes. SELECT * FROM pc AS INNER JOIN INNER JOIN INNER JOIN INNER JOIN

a memoria AS b ON (a.memoria = b.mem_id) cpu AS c ON (a.cpu = c.cpu_id) disco AS d ON (a.disco = d.disco_id) tgrafica AS e ON (a.tgrafica = e.tgraf_id);

Una vez que hemos combinado todas las tablas, vamos a definir los atributos que queremos presentar en nuestro resultado. Utilizaremos los prefijos de tablas definidos en la consulta anterior (a,b,c,d,e), para acceder a los atributos de cada tabla: SELECT a.pcid, b.mem_tipo, b.mem_capacidad AS mem_MB, c.cpu_fabricante AS cpu_fab, c.cpu_tipo, d.disco_fabricante AS disco_fab, d.disco_capacidad AS disco_GB, e.tgraf_fabricante AS tgraf_fab, a.precio FROM pc AS a

INNER INNER INNER INNER

JOIN JOIN JOIN JOIN

memoria AS b ON (a.memoria = b.mem_id) cpu AS c ON (a.cpu = c.cpu_id) disco AS d ON (a.disco = d.disco_id) tgrafica AS e ON (a.tgrafica = e.tgraf_id);

Y para terminar ordenamos el resultado: SELECT a.pcid, b.mem_tipo, b.mem_capacidad AS mem_MB, c.cpu_fabricante AS cpu_fab, c.cpu_tipo, d.disco_fabricante AS disco_fab, d.disco_capacidad AS disco_GB, e.tgraf_fabricante AS tgraf_fab, a.precio FROM pc AS a INNER JOIN memoria AS b ON (a.memoria = b.mem_id) INNER JOIN cpu AS c ON (a.cpu = c.cpu_id) INNER JOIN disco AS d ON (a.disco = d.disco_id) INNER JOIN tgrafica AS e ON (a.tgrafica = e.tgraf_id) ORDER BY precio DESC; El resultado de nuestra consulta presentar las caractersticas de solo los PC completos: pcid | mem_tipo | mem_mb | cpu_fab | cpu_tipo | disco_fab | disco_gb | tgraf_fab | precio ------+------------+--------+---------+------------+-----------+---------+-----------+-------4 | DDR3 SDRAM | 2048 | amd | Athlon X2 | samsung | 500 | nvidia | 1600 3 | DDR2 SDRAM | 1024 | intel | Core2 Quad | seagate | 1024 | nvidia | 1400 2 | DDR SDRAM | 1024 | intel | Core2 duo | seagate | 500 | ati | 1100 1 | DDR SDRAM | 1024 | intel | Core2 duo | seagate | 350 | ati | 1000 (4 rows) Consulta 2 Obtener una relacin de todos los modelos de PC a la venta. Queremos toda la informacion disponible sobre los componentes que lo forman. Ordenar el resultado de mayor a menor precio.

En esta consulta nos piden lo mismo que la consulta 1 pero de todos los modelos de PC, los completos y los que se venden sin algun componente. La tabla PC es la tabla principal de nuestra combinacin, y la tabla a la que le faltan valores en ciertos atributos en algunas tuplas. Esta tabla es la primera que se define cuando definimos las clusulas JOIN y por definicin es la que se encuentra ms a la izquierda. Por ello utilizaremos el tipo LEFT OUTER JOIN para conseguir el resultado de la consulta 1, mas todos los PC a los que le falta algn componente. Lo nico que tenemos que hacer es cambiar INNER JOIN por LEFT OUTER JOIN. La consulta quedaria asi: SELECT a.pcid, b.mem_tipo, b.mem_capacidad AS mem_MB, c.cpu_fabricante AS cpu_fab, c.cpu_tipo, d.disco_fabricante AS disco_fab, d.disco_capacidad AS disco_GB, e.tgraf_fabricante AS tgraf_fab, a.precio FROM pc AS a LEFT OUTER JOIN memoria AS b ON (a.memoria = b.mem_id) LEFT OUTER JOIN cpu AS c ON (a.cpu = c.cpu_id) LEFT OUTER JOIN disco AS d ON (a.disco = d.disco_id) LEFT OUTER JOIN tgrafica AS e ON (a.tgrafica = e.tgraf_id) ORDER BY precio DESC; Y el resultado de nuestra consulta presentar las caractersticas de todos los PC: pcid | mem_tipo | mem_mb | cpu_fab | cpu_tipo | disco_fab | disco_gb | tgraf_fab | precio ------+------------+--------+---------+------------+-----------+---------+-----------+-------4 | DDR3 SDRAM | 2048 | amd | Athlon X2 | samsung | 500 | nvidia | 1600 3 | DDR2 SDRAM | 1024 | intel | Core2 Quad | seagate | 1024 | nvidia | 1400

2 | DDR SDRAM | 1024 500 | ati | 1100 1 | DDR SDRAM | 1024 350 | ati | 1000 5 | | 350 | ati | 900 6 | | | ati | 400 (6 rows) Consulta 3

| intel | intel | intel |

| Core2 duo | Core2 duo | Core2 duo |

| seagate | seagate | seagate |

| | | |

Obtener una relacin de solo los modelos de 'PC NO completos' a la venta. Queremos toda la informacin disponible sobre los componentes que lo forman Si os fijais esta consulta la podriamos obtener si al resultado que muestra todos los PCs, le 'restamos' el resultado con solo los PCs completos. Esto lo podriamos realizar combinando la consulta 1 con la consulta 2 mediante el operador EXCEPT (consulta 2 EXCEPT consulta 1): ( SELECT a.pcid, b.mem_tipo, b.mem_capacidad AS mem_MB, c.cpu_fabricante AS cpu_fab, c.cpu_tipo, d.disco_fabricante AS disco_fab, d.disco_capacidad AS disco_GB, e.tgraf_fabricante AS tgraf_fab, a.precio FROM pc AS a LEFT OUTER JOIN memoria AS b ON (a.memoria = b.mem_id) LEFT OUTER JOIN cpu AS c ON (a.cpu = c.cpu_id) LEFT OUTER JOIN disco AS d ON (a.disco = d.disco_id) LEFT OUTER JOIN tgrafica AS e ON (a.tgrafica = e.tgraf_id) ) EXCEPT ( SELECT a.pcid, b.mem_tipo, b.mem_capacidad AS mem_MB, c.cpu_fabricante AS cpu_fab, c.cpu_tipo,

d.disco_fabricante AS disco_fab, d.disco_capacidad AS disco_GB, e.tgraf_fabricante AS tgraf_fab, a.precio FROM pc AS a INNER JOIN memoria AS b ON (a.memoria = b.mem_id) INNER JOIN cpu AS c ON (a.cpu = c.cpu_id) INNER JOIN disco AS d ON (a.disco = d.disco_id) INNER JOIN tgrafica AS e ON (a.tgrafica = e.tgraf_id) ) ORDER BY precio DESC; El resultado seria el esperado: pcid | mem_tipo | mem_mb | cpu_fab | cpu_tipo | disco_fab | disco_gb | tgraf_fab | precio ------+----------+--------+---------+-----------+-----------+---------+-----------+-------5 | | | intel | Core2 duo | seagate | 350 | ati | 900 6 | | | | | | | ati | 400 (2 rows) Consulta 4 Obtener una relacin de todos los PC que tengan CPUs de AMD y discos Samsung. Queremos toda la informacin disponible sobre los componentes que lo forman El trabajo para definir esta consulta est casi hecho. Lo nico que tenemos que hacer es aplicar mediante la sentencia WHERE, las dos condiciones que nos piden, a la consulta 2: SELECT a.pcid, b.mem_tipo, b.mem_capacidad AS mem_MB, c.cpu_fabricante AS cpu_fab, c.cpu_tipo, d.disco_fabricante AS disco_fab, d.disco_capacidad AS disco_GB, e.tgraf_fabricante AS tgraf_fab, a.precio FROM pc AS a

LEFT OUTER JOIN memoria AS b ON (a.memoria = b.mem_id) LEFT OUTER JOIN cpu AS c ON (a.cpu = c.cpu_id) LEFT OUTER JOIN disco AS d ON (a.disco = d.disco_id) LEFT OUTER JOIN tgrafica AS e ON (a.tgrafica = e.tgraf_id) WHERE c.cpu_fabricante = 'amd' AND d.disco_fabricante = 'samsung' ORDER BY precio DESC; Y el resultado quedaria asi: pcid | mem_tipo | mem_mb | cpu_fab | cpu_tipo | disco_fab | disco_gb | tgraf_fab | precio ------+------------+--------+---------+-----------+-----------+---------+-----------+-------4 | DDR3 SDRAM | 2048 | amd | Athlon X2 | samsung | 500 | nvidia | 1600 (1 row) Consulta 5 Obtener una relacin del numero de PCs que tienen CPUs de Intel y de AMD. Ordenar de mayor a menor. Esta consulta es un poco diferente a las anteriores. Aqu tenemos que agrupar los resultados segn el fabricante de la CPU utilizada, y contar cuantas tuplas existen en cada grupo. Al necesitar solamente informacin contenida en la tabla 'CPU', solo tendremos que combinar la tabla 'PC' con la tabla 'CPU'. Como queremos obtener solamente los PC que tienen algun tipo de CPU, utilizaremos un INNER JOIN para descartar los PCs sin CPU definida. SELECT * FROM pc AS a INNER JOIN cpu AS b ON (a.cpu = b.cpu_id); A continuacin vamos a agrupar el resultado obtenido segun el fabricante de la CPU y contaremos el nmero de tuplas en cada grupo: SELECT b.cpu_fabricante, count(*) AS total

FROM pc AS a INNER JOIN cpu AS b ON (a.cpu = b.cpu_id) GROUP BY b.cpu_fabricante; Y ordenamos el resultado: SELECT b.cpu_fabricante, count(*) AS total FROM pc AS a INNER JOIN cpu AS b ON (a.cpu = b.cpu_id) GROUP BY b.cpu_fabricante ORDER BY total DESC; El resultado obtenido seria: cpu_fabricante | total ----------------+------intel | 4 amd | 1 (2 rows) En fin, espero que os hagais una idea de como funciona el tema de combinar diferentes tablas para obtener un resultado. En la vida real os encontrareis con ejemplos bastantes complicados, lo importante es pensar la estrategia a seguir antes de empezar a escribir la consulta SQL. Tambin es importante hacerlo paso a paso, aplicando las restricciones necesarias hasta conseguir lo que queremos. Solamente la prctica os ayudar a entender y escribir con soltura consultas complejas.

Vistas en SQL Muchas bases de datos relacionales que se utilizan en aplicaciones del mundo real tienen esquemas complejos y formados por muchas tablas. En ocasiones, es conveniente que algunos grupos o perfiles de usuarios tengan una vista parcial de ese esquema, o que tengan una visin de la misma con una estructura diferente a la del esquema que realmente est almacenado. Precisamente para estos casos, el lenguaje SQL permite definir vistas.

Una vista es esencialmente una consulta almacenada que devuelve un conjunto de resultados y a la que se le pone un nombre. Una vista es una tabla virtual, aparece como una tabla ms del esquema, aunque realmente no lo es. Sintaxis La sintaxis general para crear una vista es la siguiente: CREATE VIEW view_name [(column_list)] AS sentencia_select La idea es muy simple, solamente le damos nombre (view_name) a una consulta. Opcionalmente, los atributos de la relacin resultante de la sentencia_select pueden renombrarse mediante etiquetas en column_list. Un ejemplo Tomemos como ejemplo una aplicacin muy simple de gestin de pedidos en un supermercado virtual. El esquema relacional sera el siguiente.

Figura 1 En ese esquema, la informacin aparece descompuesta en tablas. Sin embargo, para un usuario en un departamento de marketing, podra ser que le fuese ms til tener la informacin de las ventas de los productos acumuladas, simplemente. CREATE VIEW resumenproductos AS select p.id, p.nombre, sum(cantidad) AS total from producto as p, lineas_pedido as l

where (l.producto = p.id) group by l.producto order by total desc Despus de definir la vista, podremos utilizar resumenproductos como si fuese una tabla ms. Por ejemplo la sentencia: select * from resumenproductos Nos devolver el resultado de la consulta que define la vista. Como segundo ejemplo, puede que una persona en Contabilidad solamente necesite el resumen econmico de los pedidos. En ese caso, podremos definir una vista como la siguiente utilizando una subconsulta correlacionada: CREATE VIEW resumenpedidos (usuario, nombre, pedido, fecha, total) ASSELECT c.usuario, c.nombre, p.numpedido, p.fecha, (SELECT SUM(precio*cantidad) FROM LINEAS_PEDIDO as x WHERE (x.cliente = p.cliente) and (x.pedido=p.numpedido))FROM CLIENTES as C, PEDIDOS as PWHERE p.cliente = c.usuario El resultado sera como el siguiente: usuario nombre pedido fecha total agarcia Ana Garcia 1 2008-11-05 40 jlopez Juan Lopez 1 2008-02-10 65 jlopez Juan Lopez 2 2008-02-11 null Tabla 1 Ntese que cuando un pedido no tiene lneas asociadas, aparecer un nulo en la subconsulta. La consulta puede hacerse tambin mediante agrupamiento con la siguiente consulta: SELECT c.usuario, c.nombre, p.numpedido, p.fecha, sum(cantidad*precio) FROM clientes as c, pedidos as p, lineas_pedido as l WHERE (c.usuario = p.cliente) and (p.cliente = l.cliente) and (p.numpedido=l.pedido) GROUP BY p.cliente, p.numpedido En este caso se evita la aparicin de nulos, ya que la clusula GROUP BY no crear un subgrupo en el caso de que no haya lneas de pedido. Lgicamente, los beneficios de las vistas se obtienen al combinar su definicin con el sistema de permisos del gestor de base de datos. Siguiendo el ejemplo, daramos permiso a los usuarios en Marketing sobre la vista resumenproductos, y permisos a los usuarios de Contabilidad sobre resumenpedidos.

La representacin de las vistas Dado que las vistas aparecen como tablas, pueden aparecer en otras consultas. Es importante tener esto en cuenta cuando se estn diseando consultas, dado que puede afectar al rendimiento. Para ello, algunos gestores de bases de datos tienen sintaxis extendidas para controlar cmo se representan internamente las vistas. Por ejemplo, MySQL tiene una clusula ALGORITHM que puede acompaarse de tres valores: MERGE,TEMPTABLE o UNDEFINED, con el siguiente significado:

Con MERGE, el texto de las sentencias que hagan referencia a una vista se fusiona con el texto de la definicin de la vista, de modo que las partes de la definicin de la vista reemplazan a las partes correspondientes de la sentencia. Con TEMPTABLE, los resultados de la vista se recuperan en una tabla temporal, que se usa despus para ejecutar la consulta.

El uso de TEMPTABLE consume un espacio temporal adicional, pero puede tener un mejor rendimiento ya que despus de hacer la copia de los datos en la tabla temporal, se usa sta y se libera la tabla o tablas originales.

Modificacin de las bases de datos.

SQL posee comandos destinados tambin para modificar la base de datos, entre estos se tienen operaciones de borrado, insercin y actualizacin.

6.10.1 BORRADO

La operacin de borrado se expresa de igual manera que una consulta. Se pueden borrar slo tuplas completas, es decir, no se pueden borrar valores de atributos concretos.

La expresin SQL relacionada con el borrado es:

delete from r where p

Donde r es una relacin y p es una condicin lgica que determina las tuplas a ser eliminadas de r, si la condicin p es omitida, se eliminan todas la tuplas de r.

Hay que sealar que una orden delete opera slo sobre una relacin. Si se desea borrar tuplas de varias relaciones, se deber utilizar una orden delete por cada relacin. El predicado de la clusula where puede ser tan complicado como el where de cualquier clusula select, o tan simple como una clusula where vaca.

Ejemplo: Borrar todas las tuplas de la relacin Prestamo (Los sistemas bien diseados requerirn una confirmacin del usuario antes de ejecutar una consulta como esta).

Solucin: delete from Prestamo

Ejemplo: Borrar todas las cuentas de la Sucursal Subtiava

Solucin: delete from Cuenta where nombre_sucursal=Subtiava

Ejemplo: Borrar todas las cuentas de la Sucursal Subtiava

Solucin: delete from Cuenta where nombre_sucursal=Subtiava

Ejemplo: Borrar todos los prstamos en los que el monto del prstamo est entre C$ 5,000 y C$ 10,000 crdobas.

Solucin: delete from Prestamo where importe between 5000 and 10000

Ejemplo: Borrar las cuentas de todas las sucursales de Granada

En este caso la solucin se genera mediante una subconsulta que muestra los nombres de las sucursales ubicadas en Masaya. De modo que la expresin SQL requerida es:

Solucin: delete from Cuenta where nombre_sucursal in (select nombre_sucursal from Sucursal where ciudad_sucursal = Granada)

En este borrado se se selecciona primero todas las sucursales con sede en Granada y a continuacin borra todas las tuplas Cuenta pertenecientes a esas sucursales.

6.106.1.1 Uso de funciones de agregacin en una subconsulta de borrado.

Ejemplo: Borrar todas las cuentas cuyos saldos sean inferiores a la media del banco

Solucin: delete from Cuenta where saldo < << <(select avg (saldo) from Cuenta)

La orden delete comprueba primero que cada tupla de la relacin Cuenta para comprobar si la cuenta tiene un saldo inferior a la media del banco. A continuacin se borran todas las tuplas que no cumplan la condicin anterior, es decir, las que representan una cuenta con un saldo menor que la media. Es importante realizar todas las comprobaciones antes de llevar a cabo ningn borrado.

6.106.2 INSERCIN

El comando SQL encargado de realizar la insercin de una ms tuplas en una relacin es el comando insert, este tiene dos variantes:

Una para insertar una sola tupla indicando los valores de los atributos de forma explcita, la forma general en este caso es insert into r values (tupla a insertar) en el caso de que se respete el orden de los atributos en la relacin r, En caso de que la tupla a insertar no respete ese orden, el nombre de los atributos se debe listar tambin en el comando insert.

Para insertar datos en una relacin, o bien se especifica la tupla que se desea insertar o se formula una consulta cuyo resultado sea el conjunto de tuplas que se desean insertar. Obviamente, los valores de los atributos de las tuplas que se inserten deben pertenecer al dominio de los atributos. De igual manera, las tuplas insertadas debern ser de la aridad correcta.

La instruccin insert ms sencilla corresponde a la de insercin de una tupla.

Ejemplo: Insertar en la base los datos asociados a la cuenta C?0045 en la Sucursal Lon y que tiene como saldo C$ 6000.00

Solucin Caso 1: insert into Cuenta values ( C?0045, Len, 6000)

En este ejemplo los valores se especifican en el mismo orden en que los atributos se listan en el esquema de la relacin Cuenta. Para beneficio de los usuarios que no pueden recordar el orden de los atributos se especifican en la clusula insert.

Solucin Caso 2: insert into Cuenta (nombre_sucursal, numero_cuenta, saldo) values (Len,C?0045,6000)

Solucin: insert into Cuenta (numero_cuenta, nombre_sucursal, saldo) values (C? 0045,Len,6000)

El efecto es similar al ejemplo anterior con la diferencia de que se han listado explicitamente los nombres de los atributos, esto debido a que en la clusula values no se ha guardado el orden que estos tienen en la estructura de la tabla.

Generalmente se desea insertar las tuplas que resultan de una consulta.

Ejemplo: Si a todos los clientes que tienen un prstamo en la sucursal Subtiava se les quisiera regalar, como gratificacin una cuenta de ahorro con C$ 5000.00 por cada cuenta de prstamo que posee.

Solucin: insert into Cuenta select nombre_sucursal,numero_prestamo, 1000 from Prestamo where nombre_sucursal = Subtiava La instruccin select se evala primero, produciendo un conjunto de tuplas que a continuacin se insertan en la relacin Cuenta. Cada tupla tiene un nombre_sucursal (Subtiava), un numero_prestamo (que sirve como nmero para la nueva cuenta) y un saldo inicial de la cuenta (C$ 1000).

Es necesario aadir tuplas a la relacin Impositor, a travs de la siguiente consulta:

Solucin: insert into Impositor select nombre_cliente, numero_prestamo from Prestatario, Prestamo where Prestatario.numero_prestamo = Prstamo.numero_prestamo and nombre_sucursal = Subtiava

Esta consulta inserta en la relacin Impositor una tupla (nombre_cliente, numero_prestamo) por cada nombre_cliente que posea un prstamo en la sucursal Subtiva, con nmero de prstamo numero_prestamo.

6.106.3 ACTUALIZACIONES

En determinadas situaciones puede ser necesario cambiar un valor dentro de una tupla, sin cambiar todos los valores de la misma. Para este tipo de situaciones se utiliza la instruccin update. Al igual que ocurre con insert y delete, se puede elegir las tuplas que van a ser actualizadas mediante una consulta.

Forma general: Sea r una relacin y sea exp la expresin de actualizacin, entonces la forma general del comando de actualizaciones:

update r set exp

Ejemplo: Realizar el pago de intereses anuales y todos los saldos se incrementen en un 5%, habra que formular la siguiente consulta de actualizacin:

Solucin: update Cuenta set saldo=saldo * 1.05

Esta actualizacin se aplica una vez a cada tupla de la relacin Cuenta.

Ejemplo: Si se paga el inters slo a las cuentas con un saldo de C$ 1000 o superior, se puede escribir la siguiente consulta.

Solucin: update Cuenta set saldo=saldo * 1.05 where saldo >=1000

En general la clusula where de la instruccin update puede contener cualquier constructor legal en la clusula where de una instruccin select (incluyendo instrucciones select anidadas). Como con delete e insert, un select anidado en una instruccin update puede referenciar la relacin que se est actualizando. SQL, primero comprueba todas las tuplas de la relacin para determinar las que deberan actualizar y despus la actualizacin.

Ejemplo: Pagar un inters del 5% a las cuentas cuyo saldo sea mayor que la media.

Solucin: update Cuenta set saldo=saldo * 1.05 where (saldo > select avg(saldo) from Cuenta)

Ejemplo: Suponer que las cuentas con saldos superiores a C$ 5000 reciben un 6% de inters, mientras que las dems cuentas recibirn un 5%.

Solucin: update Cuenta set saldo=saldo * 1.06 where saldo > 5000

Solucin: update Cuenta set saldo=saldo * 1.05 where saldo <= 5000

Tomar en cuenta, que el orden en el que se ejecutan dos instrucciones de actualizacin es importante. Este tipo de solucin tiene el inconveniente de que si se modifica el orden de las consultas de actualizacin se pueden generar actualizaciones errneas. As si se realiza primero el incremento del 5%, valores cercanos a 1000 pasaran a ser valores mayores de 1000 con lo cual se les aplicara el 6% de incremento, llegndose a un incremento neto del 1.05 * 1.06 = 1.113 es decir el 11.3%, en lugar del 5% para evitar esta problemtica SQL cuenta con el comando case muy similar al comando de los lenguajes de propsito general, as la expresin del ejemplo anterior utilizando case es:

SQL ofrece una constructora case, que se puede usar para formular las dos instrucciones de actualizacin en una instruccin de actualizacin.

Solucin: update Cuenta set saldo = case when saldo <= 10000 then saldo * 1,05 else saldo * 1.06 end

La forma general de la clusula case es:

case when pred1 then result1 when pred2 then result2 when predn then resultn else result0 end

En este caso se analizan cada uno de los predicados y si predi es verdadero entonces se ejecuta resulti. Por otra parte si ninguno es verdadero se ejecuta result0. 6.107 TRANSACCIONES

Una transaccin es un conjunto de instrucciones SQL de consultas y actualizaciones que deben de ejecutarse todas de forma exitosa o no ejecutar ninguna. La norma SQL especifica que una transaccin comienza de forma implcita (no hay comando de comienzo) cuando se ejecuta una instruccin SQL, la transaccin finaliza con cualquiera de las siguientes opciones dependiendo de la decisin del usuario.

Commit: Compromete la Transaccin actual, es decir hace que los cambios realizados por la transaccin sean permanentes en la base de datos. Despus de ejecutarse este comando comienza una nueva transaccin de forma automtica

RollBack: Su efecto es retroceder la transaccin actual es decir deshace todas las actualizaciones realizadas por las instrucciones SQL, de tal forma que la base de datos se restaura al estado que exista previo a la primera instruccin de la transaccin.

Lenguaje SQL Insercin y modificacin de datos ^ Llegamos ahora a un punto interesante, una base de datos sin datos no sirve para mucho, de modo que veremos cmo agregar, modificar o eliminar los datos que contienen nuestras bases de datos. Insercin de nuevas filas ^ La forma ms directa de insertar una fila nueva en una tabla es mediante una sentencia INSERT. En la forma ms simple de esta sentencia debemos indicar la tabla a la que queremos aadir filas, y los valores de cada columna. Las columnas de tipo cadena o fechas deben estar entre comillas sencillas o dobles, para las columnas nmericas esto no es imprescindible, aunque tambin pueden estar entrecomilladas. mysql> INSERT INTO gente VALUES ('Fulano','1974-04-12'); Query OK, 1 row affected (0.05 sec) mysql> INSERT INTO gente VALUES ('Mengano','1978-06-15'); Query OK, 1 row affected (0.04 sec) mysql> INSERT INTO gente VALUES -> ('Tulano','2000-12-02'), -> ('Pegano','1993-02-10'); Query OK, 2 rows affected (0.02 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM gente; +---------+------------+ | nombre | fecha | +---------+------------+ | Fulano | 1974-04-12 | | Mengano | 1978-06-15 | | Tulano | 2000-12-02 | | Pegano | 1993-02-10 | +---------+------------+ 4 rows in set (0.08 sec) mysql> Si no necesitamos asignar un valor concreto para alguna columna, podemos asignarle el valor por defecto indicado para esa columna cuando se cre la tabla, usando la palabra DEFAULT:

mysql> INSERT INTO ciudad2 VALUES ('Perillo', DEFAULT); Query OK, 1 row affected (0.03 sec) mysql> SELECT * FROM ciudad2; +---------+-----------+ | nombre | poblacion | +---------+-----------+ | Perillo | 5000 | +---------+-----------+ 1 row in set (0.02 sec) mysql> En este caso, como habamos definido un valor por defecto para poblacin de 5000, se asignar ese valor para la fila correspondiente a 'Perillo'. Otra opcin consiste en indicar una lista de columnas para las que se van a suministrar valores. A las columnas que no se nombren en esa lista se les asigna el valor por defecto. Este sistema, adems, permite usar cualquier orden en las columnas, con la ventaja, con respecto a la anterior forma, de que no necesitamos conocer el orden de las columnas en la tabla para poder insertar datos: mysql> INSERT INTO ciudad5 (poblacion,nombre) VALUES -> (7000000, 'Madrid'), -> (9000000, 'Pars'), -> (3500000, 'Berln'); Query OK, 3 rows affected (0.05 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> SELECT * FROM ciudad5; +-------+--------+-----------+ | clave | nombre | poblacion | +-------+--------+-----------+ | 1 | Madrid | 7000000 | | 2 | Pars | 9000000 | | 3 | Berln | 3500000 | +-------+--------+-----------+ 3 rows in set (0.03 sec) mysql> Cuando creamos la tabla "ciudad5" definimos tres columnas: 'clave', 'nombre' y 'poblacion' (por ese orden). Ahora hemos insertado tres filas, en las que hemos omitido la clave, y hemos alterado el orden de 'nombre' y 'poblacion'. El valor de la 'clave' se calcula automticamente, ya que lo hemos definido como auto-incrementado. Existe otra sintaxis alternativa, que consiste en indicar el valor para cada columna: mysql> INSERT INTO ciudad5 -> SET nombre='Roma', poblacion=8000000; Query OK, 1 row affected (0.05 sec)

mysql> SELECT * FROM ciudad5; +-------+--------+-----------+ | clave | nombre | poblacion | +-------+--------+-----------+ | 1 | Madrid | 7000000 | | 2 | Pars | 9000000 | | 3 | Berln | 3500000 | | 4 | Roma | 8000000 | +-------+--------+-----------+ 4 rows in set (0.03 sec) mysql> Una vez ms, a las columnas para las que no indiquemos valores se les asignarn sus valores por defecto. Tambin podemos hacer esto usando el valor DEFAULT. Para las sintaxis que lo permiten, podemos observar que cuando se inserta ms de una fila en una nica sentencia, obtenemos un mensaje desde MySQL que indica el nmero de filas afectadas, el nmero de filas duplicadas y el nmero de avisos. Para que una fila se considere duplicada debe tener el mismo valor que una fila existente para una clave principal o para una clave nica. En tablas en las que no exista clave primaria ni ndices de clave nica no tiene sentido hablar de filas duplicadas. Es ms, en esas tablas es perfectamente posible que existan filas con los mismos valores para todas las columnas. Por ejemplo, en mitabla5 tenemos una clave nica sobre la columna 'nombre': mysql> INSERT INTO mitabla5 (id, nombre) VALUES -> (1, 'Carlos'), -> (2, 'Felipe'), -> (3, 'Antonio'), -> (4, 'Carlos'), -> (5, 'Juan'); ERROR 1062 (23000): Duplicate entry 'Carlos' for key 1 mysql> Si intentamos insertar dos filas con el mismo valor de la clave nica se produce un error y la sentencia no se ejecuta. Pero existe una opcin que podemos usar para los casos de claves duplicadas: ON DUPLICATE KEY UPDATE. En este caso podemos indicar a MySQL qu debe hacer si se intenta insertar una fila que ya existe en la tabla. Las opciones son limitadas: no podemos insertar la nueva fila, sino nicamente modificar la que ya existe. Por ejemplo, en la tabla 'ciudad3' podemos usar el ltimo valor de poblacin en caso de repeticin: mysql> INSERT INTO ciudad3 (nombre, poblacion) VALUES -> ('Madrid', 7000000); Query OK, 1 rows affected (0.02 sec) mysql> -> -> -> INSERT INTO ciudad3 (nombre, poblacion) VALUES ('Pars', 9000000), ('Madrid', 7200000) ON DUPLICATE KEY UPDATE poblacion=VALUES(poblacion);

Query OK, 3 rows affected (0.06 sec) Records: 2 Duplicates: 1 Warnings: 0 mysql> SELECT * FROM ciudad3; +--------+-----------+ | nombre | poblacion | +--------+-----------+ | Madrid | 7200000 | | Pars | 9000000 | +--------+-----------+ 2 rows in set (0.00 sec) mysql> En este ejemplo, la segunda vez que intentamos insertar la fila correspondiente a 'Madrid' se usar el nuevo valor de poblacin. Si en lugar de VALUES(poblacion) usamos poblacion el nuevo valor de poblacin se ignora. Tambin podemos usar cualquier expresin: mysql> INSERT INTO ciudad3 (nombre, poblacion) VALUES -> ('Pars', 9100000) -> ON DUPLICATE KEY UPDATE poblacion=poblacion; Query OK, 2 rows affected (0.02 sec) mysql> SELECT * FROM ciudad3; +--------+-----------+ | nombre | poblacion | +--------+-----------+ | Madrid | 7200000 | | Pars | 9000000 | +--------+-----------+ 2 rows in set (0.00 sec) mysql> INSERT INTO ciudad3 (nombre, poblacion) VALUES -> ('Pars', 9100000) -> ON DUPLICATE KEY UPDATE poblacion=0; Query OK, 2 rows affected (0.01 sec) mysql> SELECT * FROM ciudad3; +--------+-----------+ | nombre | poblacion | +--------+-----------+ | Madrid | 7200000 | | Pars | 0 | +--------+-----------+ 2 rows in set (0.00 sec) mysql> Reemplazar filas ^

Existe una sentencia REPLACE, que es una alternativa para INSERT, que slo se diferencia en que si existe algn registro anterior con el mismo valor para una clave primaria o nica, se elimina el viejo y se inserta el nuevo en su lugar. REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name [(col_name,...)] VALUES (,...),(...),... REPLACE [LOW_PRIORITY | DELAYED] [INTO] tbl_name SET col_name=, ... mysql> REPLACE INTO ciudad3 (nombre, poblacion) VALUES -> ('Madrid', 7200000), -> ('Pars', 9200000), -> ('Berln', 6000000); Query OK, 5 rows affected (0.05 sec) Records: 3 Duplicates: 2 Warnings: 0 mysql> SELECT * FROM ciudad3; +--------+-----------+ | nombre | poblacion | +--------+-----------+ | Berln | 6000000 | | Madrid | 7200000 | | Pars | 9200000 | +--------+-----------+ 3 rows in set (0.00 sec) mysql> En este ejemplo se sustituyen las filas correspondientes a 'Madrid' y 'Pars', que ya existan en la tabla y se inserta la de 'Berln' que no estaba previamente. Las mismas sintaxis que existen para INSERT, estn disponibles para REPLACE: mysql> REPLACE INTO ciudad3 VALUES ('Roma', 9500000); Query OK, 1 rows affected (0.03 sec) mysql> REPLACE INTO ciudad3 SET nombre='Londres', poblacion=10000000; Query OK, 1 row affected (0.03 sec) mysql> SELECT * FROM ciudad3; +---------+-----------+ | nombre | poblacion | +---------+-----------+ | Berln | 6000000 | | Londres | 10000000 | | Madrid | 7200000 | | Pars | 9200000 | | Roma | 9500000 | +---------+-----------+

5 rows in set (0.00 sec) mysql>

También podría gustarte