Você está na página 1de 34

Manipulacin de datos 6.1 Introduccin Ahora abordaremos los aspectos de manipulacin de datos de SQL.

Este lenguaje ofrece cuatro proposiciones en DML SELECT (seleccionar), UPDATE (actualizar), DELETE ( borrar) e INSERT (insertar)- el presente capitulo describe las caracteristicas principales de los cuatro. Como se explico en la seccin 4.3 las tablas manipuladas con esas proposiciones de DML pueden ser, en trminos generales, tanto tablas base como vistas. Pero este capitulo nos ocuparemos de manera exclusiva de las tablas base. Las vistas se analizan en el captulo 8. Este capitulo esta organizado como sigue: las secciones 6.2 a 6.5 se ocupan de las operaciones de recuperacin de datos y la seccin 6.6 estudia las operaciones de actualizacin ( trmino en el cual incluimos, como ya es costumbre, todas las operaciones con UPDATE, DELETE e INSERT) en trminos ms especficos: La seccin 6.2 presenta las caractersticas principales de la proposicin select bsica La seccin 6.3 explica como puede utilizarse select para expresar diversos tipos de reunin ( en particular, la llamada reunin natural). La seccin 6.4 analiza las funciones de agregados COUNT (cuenta), SUM (suma) AVG (promedio), etctera; en particular describe el empleo de las clusulas GROUP BY (agrupar por) y HAVING (con) junto con esas funciones. La seccin 6.5 describe varias caractersticas adicionales: LIKE (como), la condicin IS NULL (es nulo), subconsultas, EXISTS (existe) y UNION (unin). Estas construcciones, aunque bastante importante en algunos casos, suelen utilizarse con menor frecuencia en la prctica que las que se describen en las secciones 6.2 a 6.4 razn por la cual se revisa en una seccin aparte. La seccin 6.6 esta dedicada a las proposiciones UPDATE (actualizar), DELETE (eleiminar) e INSERT (insertar). Por ultimo trataremos de vincular varias de las ideas presentadas en el cuerpo del capitulo. Para ello la seccin 6.7 presentar como ejemplo una consulta muy compleja y mostrar en principio cmo podra ejecutarse.

No es nuestra intencin ofrecer un tratamiento complejo del lenguaje de manipulacin de datos (DML) de SQL; slo queremos ilustrar sus caractersticas principales. Con todo, el capitulo es bastante largo, y el lector quiz prefiera abordarlo seccin por seccin. La seccin 6.5 puede omitirse en una primera lectura, si se desea. Nota: muchos de los ejemplos siguientes sobre todo los de la seccin 6.5 son bastante complejos. El lector deber sacar la conclusin de que lo complejo radica en el lenguaje SQL mismo, con ello queremos subrayar ms bien el hecho de que las operaciones comunes son tan sencillas en SQL (y, de hecho, en casi todos los lenguajes relacionales) que los ejemplos de tales operaciones resultan poco interesantes, y no iluistran toda la potencia del lenguaje. Por supuesto, tambin mostraremos algunos ejemplos sencillos. Como siempre, los ejemplos utilizan la base de datos de proveedores y partes. 6.2 CONSULTAS SIMPLES

Comenzaremos con un ejemplo sencillo: la consulta debe obtener el nmero y la situacin de todos los proveedores de Pars la cual puede expresarse en SQL as: SELECT S#, SITUACION FROM S WHERE CIUDAD = Pars; -----------------Resultado: S# Situacin ---------------S2 10 S3 30 Este ejemplo ilustra la forma ms comn de la proposicin SELECT en SQL: SELECT (seleccionar) los campos especificados FROM (de) la tabla especificada WHERE (donde) se cumpla la condicin especificada. El primer punto por destacar es que el resultado de la consulta es otra tabla, derivada en alguna forma de las tablas existentes en la base de datos. Dicho de otro modo, el usuario de un sistema relacional trabaja siempre dentro del marco de referencia tabular sencillo, lo cual es una caracterstica muy atractiva de esos sistemas. (por esta razn decidimos que las tablas relacionales constituyen un sistema cerrado bajo los operadores de recuperacin de datos de un lenguaje como SQL. Hablaremos muchos ms de cerca de la cerradura en la parte III del presente libro.) Por cierto podramos haber formulado la consulta empleando nombres de campo calificados en todos los casos: SELECT S.S# , S.SITUACIN FROM S WHERE S.CIUDAD = Pars Un nombre de campo calificado se compone de un nombre de tabla ( o nombre de variable de recorrido) y un nombre de campo, en ese orden, separados mediante un punto. Nunca es indebido utilizar nombres calificados, y en algunos casos es indispensable, como se ver en la seccin 6.3. Como referencia, mostramos enseguida la forma general de la proposicin SELECT ( pasando por alto la posibilidad de UNION, la cual se explicara ms delante de este capitulo): SELECT [DISTINCT] elemento (s) FROM tabla (s) [WHERE condicin] [GROUP BY campo(s)] [HAVING condicin] [ ORDER BY campo (s)]; Enseguida mostraremos las caractersticas principales de esta proposicin mediante una seria bastante larga de ejemplos. 6.2.1 RECUPERACIN SIMPLE Obtener los nmeros de parte de todas las partes suministradas .

SELECT P# FROM tabla (s) RESULTADO:

P# P1 P2 P3 P4 P5 P6 P1 P2 P2 P2 P4 P5

Obsrvese la repeticin de nmeros de parte en este resultado. SQL no elimina filas repetidas del resultado de una proposicin SELECT si el usuario no se lo pide de manera explcita mediante la palabra DISTINT (distinto), como en: SELECT DISTINT P# FROM SP; RESULTADO: P# P1 P2 P3 P4 P5 P6 Nota: en este ejemplo especifico sucede que cada fila contiene un nuevo valor escalar; por tanto, el efecto de DISTINT en este caso es eliminar valores escalares repetidos. Pero ntese, que en general el significado de DISTINT es eliminar filas repetidas. Vase el ejemplo 6.3.5 en la siguiente seccin como ilustracin. 6.2.2 Recuperacin de valores calculados. Obtener, para todas las partes, el nmero de parte y su peso en gramos ( los pesos de partes se dan en libras en la tabla P). SELECT P.P#, peso en gramos =, P. PESO * 454 FROM P ----- -----------------------------Resultado P# ---- -----------------------------P1 peso en gramos = 5448 P2 peso en gramos = 7718 P3 peso en gramos = 7718 P4 peso en gramos = 6356

P5 peso en gramos = 5448 P6 peso en gramos = 8626 La clusula SELECT ( y tambin las clusulas WHERE y HAVING, vanse los ejemplos correspondientes) puede incluir expresiones escalares generales, empleando por ejemplo, operadores escalares con ms y menos y funciones escalares como SUBSTR (subcadena), en vez de nombres simples de campo, o adems de ellos. 6.2.3 Recuperacin simple ( SELECT*). Obtener datos completos de todos los proveedores. SELECT * FROM S Resultado una copia de toda la tabla S. El asterisco representa una lista de todos los nombres de campo de la tabla o tablas nombradas en la clusula FROM (de), en el orden de definicin de esos campos en las proposiciones CREATE ( y quiz ALTER) TABLE pertinentes. As la proposicin SELECT mostrada equivale a: SELECT S.S# FROM S; La notacin del asterisco es cmoda para consultas interactivas, ya sea que ahorra tecleo. No obstante, puede ser peligrosa en SQL embebido ( o sea, SQL dentro de un programa de aplicacin) porque el significado de * puede cambiar si se religa el programa y entre tanto se ha modificado de alguna forma la definicin de la tabla (sobre todo si se ha aadido otra columna). Este libro utilizara SELECT * solo en contextos donde no pueda provocar problemas ( casi en todos los contextos interactivos), y recomendamos a los usuarios hacer lo mismo en la prctica. 6.2.4. recuperacin calificada. Obtener los nmeros de los proveedores radicados en Pars cuya situacin sea mayor de que 20. SELECT S# FROM S WHERE CIUDAD = Pars AND SITUACIN > 20: ------Resultado S# -----S3 La condicin que sigue a WHERE ( donde) puede incluir los operadores de comparacin = ,<> (diferente de), >, >=, <, <=; los operadores booleanos AND, OR y NOT; y parntesis para indicar un orden de evaluacin deseado. 6.2.5 recuperacin por ordenamiento Obtener nmeros de proveedor y situacin de los proveedores en Pars, en orden descendente por situacin.

SELECT S#, SITUACION FROM S WHERE CIUDAD= Pars ORDER BY SITUACION DESC; Resultado: S# SITUACIN ------------------S3 30 S2 10 En general no se garantiza un orden particular en la tabla de resultado, pero aqu el usuario especific la organizacin del resultado en un cierto orden antes de su presentacin. El ordenamiento puede especificarse igual que en CREATE INDEX (crear ndice) como se observa en la seccin 5.3, es decir, Columna [orden ] [, columna [orden] ] Donde, como el caso de CREATE INDEX, orden puede ser asc o desc, y asc es el orden por omisin Tambin es posible identificar columnas en la clusula ORDER BY (ordenar por) empleando nmeros de columna en vez de nombres; es decir, segn la posicin ordinal (izquierda a derecha) de la columna en cuestin dentro de la tabla de resultado. Esta caracterstica hace posible utilizar como criterio de ordenamiento del resultado una columna sin nombre. Por ejemplo, si queremos organizar el resultado del ejemplo 6.2.2 en orden ascendente por nmero de parte dentro de un orden ascendente por peso en gramos: SELECT P.P#, peso en gramos =, P:PESO * 454 FROM P ORDER BY 3, P# ; /* o bien ORDER BY 3, 1;*/ El 3 se refiere a la tercera columna de la tabla de resultado, Resultado: P -------P1 P5 P4 P2 P3 P6 6.3 -----------------------------------------peso en gramos = 5448 peso en gramos = 5448 peso en gramos = 6356 peso en gramos = 7718 peso en gramos = 7718 peso en gramos = 8626

CONSULTAS DE REUNIN La posibilidad de reunir dos o ms tablas en una sola es una de las caractersticas ms poderosas de los sistemas relacionales. De hecho, la disponibilidad de la operacin de reunin es, casi ms importante que cualquier otra cosa, lo que distingue a los sistemas relacionales de los no relacionales. As pues, qu es una reunin? en trminos informales, es una consulta en la cual se

obtiene informacin de ms de una tabla de una tabla. He aqu un ejemplo sencillo. 6.3.1 Equirreunin simple.

Obtener todas las combinaciones de informacin de proveedores y partes tales que el proveedor y la parte en cuestin estn situados en la misma ciudad ( es decir, estn consituados; valga intentar un trmino antiesttico pero cmodo). SELECT S. *, P.* FROM S, P WHERE S.CIUDAD = P. CIUDAD; Advirtase que aqu las referencias a campos en la clusula WHERE deben calificarse con los nombres de las tablas correspondientes (pues de lo contrario seran ambiguas) Resultado. S# SNOMBRE SITUACIN S.CIUDAD P.NOMBRE COLOR PESO P.CIUDAD S1 S1 S1 S2 S2 S2 S2 S4 S4 S4 Salazar Salazar Salazar Jaimes Jaimes Bernal Bernal Corona Corona Corona 20 20 20 10 10 30 30 20 20 20 Londres Londres Londres Pars Pars Pars Pars Londres Londres Londres P1 Tuerca P4 Birlo P6 Tuerca P2 Perno P5 Leva P2 Perno P5 Leva P1 Tuerca P1 Birlo P6 Engrane Rojo Rojo Rojo Verde Azul Verde Azul Rojo Rojo Rojo 12 Londres 14 Londres 19 Londres 17 Pars 12 Pars 17 Pars 12 Pars 12 Londres 14 Londres 19 Londres

En este resultado hemos mostrado de manera explcita las dos columnas CIUDAD como P.CIUDAD y S.CIUDAD, por claridad. Explicacin: por el enunciado del problema en espaol es evidente que los datos requeridos provienen de dos tablas, a saber, S y P. Por tanto, en la formulacin en SQL de la consulta, nombramos primero esas dos tablas en la clusula FROM (de) y en seguida expresamos la conexin entre ellas ( o sea, el hecho de que los valores CIUDAD deben ser iguales) en la clusula WHERE (donde). Para entender el funcionamiento de esa proposicin, considrense cualesquiera dos filas, una de cada tabla; por ejemplo estas dos: S# SNOMBRE SITUACIN S.CIUDAD P.NOMBRE COLOR PESO P.CIUDAD S1 Salazar 20 Londres P4 Birlo Rojo 14 Londres

idnticas

Estas dos filas demuestran que el proveedor S1 y la parte de P1 si estn cosituadas (pues el valor de ciudad es el mismo en los dos casos). Por lo tanto, generan la fila de resultado --- ------------ ------------ ---------- ----- ----------- ------- ----- -------------S# S. nombre situacin S. ciudad P# P nombre color peso P. ciudad S1 Salazar 20 Londres P1 Tuerca Rojo 12 Lndres -------------------------------------------------------------------------------------------------(ya que la satisfacen la condicin de la clusula WHERE; a saber, S.CIUDAD = P.CIUDAD). Lo mismo sucede con las dems parejas de filas en las cuales los valores CIUDAD concuerdan. Ntese que el proveedor S5 (situado en Atenas) no aparece en el resultado, por que no hay partes almacenadas en Atenas; de manera similar, la parte P3 (almacenada en Roma) tampoco aparece en el resultado, por que no hay proveedores situados en Roma. Se dice que el resultado de esta reunin de las tablas S y P con base en valores de CIUDAD iguales. Tambin se usa el termino de reunin para designar la operacin de construir el resultado de este tipo. Se dice que la condicin S.CIUDAD = P.CIUDAD es una condicin de reunin. Dicho sea de paso, no es obligatorio emplear la igualdad como operador de la comparacin en una condicin de reunin, aunque es lo mas frecuente. El ejemplo 6.3.2 ilustra una reunin donde se emplea el operador mayor que. Pero si el operador es la igualdad, la reunin recibe a veces la designacin explcita de equirreunin. Por definicin la equirreunin debe producir un resultado de dos columnas idnticas (vase el ejemplo anterior). Si se elimina una de esas dos columnas, quedar lo que se conoce como reunin natural. He aqu un ejemplo de reunin natural( la de S y P con base en las ciudades): SELECT S#, SNOMBRE, SITUACIN, S.CIUDAD P#, PNOMBRE, COLOR, PESO FROM S, P WHERE S.CIUDAD = P.CIUDAD; La reunin natural es definitivamente el tipo de reunin ms til; tanto as que el termino reunin sin calificativo casi siempre se emplea para referirse de manera especifica a la reunin natural. Enseguida se presenta una forma distinta ( y til) de enfocar la construccin conceptual de las reuniones. Primero, se forma el producto se forma el producto cartesiano de las tablas incluidas en la clusula FROM (de). El producto cartesiano de un conjunto de n tablas es la tabla formada por las filas f posibles, donde f es la concatenacin de una fila de la primera tabla, una fila de la segunda tabla,, y una fila de la ensima tabla, por ejemplo, el producto cartesiano de la tabla s y la tabla p (en ese orden) es la siguiente tabla:

S# S1 S1 S1 S1 S1 S1 S2 . . . S5

S nombre Salazar Salazar Salazar Salazar Salazar Salazar Jaimes

Situacin 20 20 20 20 20 20 10

Ciudad Londres Londres Londres Londres Londres Londres Pars

P# P1 P2 P3 P4 P5 P6 P1

P nombre Tuerca Perno Birlo Birlo Leva Engrane Tuerca

Color rojo verde Azul rojo Azul rojo rojo

Peso 12 17 17 14 12 19 12

Ciudad Londres Pars Roma Londres Pars Londres Londres

Aldana

30

Atenas

P6

Engrane

rojo

19

Londres

La tabla contiene 5*6 =30 filas. Elimnense ahora de este producto cartesiano todas las filas que no satisfagan la condicin de reunin. Lo restante es la reunin requerida. En el presente caso, eliminamos todas las filas en las cuales S. CIUDAD no es igual a P. CIUDAD y lo que queda exactamente es la equirreunin antes mostrada. 6.3.2 Reunin mayor que Obtener todas las combinaciones de informacin de proveedor y parte donde la ciudad del proveedor siga a la ciudad de la parte en el orden alfabetico. SELECT S.*, P.* FROM S, P WHERE S.CIUDAD > P.CIUDAD; Resultado S# S2 S2 S2 S3 S3 S3 S nombre Jaimes Jaimes Jaimes Bernal Bernal Bernal Situacin 10 10 10 30 30 30 Ciudad Pars Pars Pars Pars Pars Pars P# P1 P4 P6 P1 P4 P6 P nombre Tuerca Birlo Engrane Tuerca Birlo Engrane Color rojo rojo rojo rojo rojo rojo Peso 12 14 19 12 14 19 Ciudad Londres Londres Londres Londres Londres Londres

6.3.3 Consulta de reunin con una condicin adicional. Obtener todas las combinaciones de informacin del proveedor y parte donde el proveedor y la parte en cuestin estn cosituados, pero omitiendo a los proveedores cuya situacin sea 20 SELECT S.*, P.P# FROM S, P WHERE S.CIUDAD = P.CIUDAD

AND S.SITUACIN <> 20;

Resultado: S# S2 S2 S3 S3 S nombre Jaimes Jaimes Bernal Bernal Situacin 10 10 30 30 Ciudad Pars Pars Pars Pars P# P2 P5 P2 P5 P nombre Perno Leva Perno Leva Color Verde Azul Verde azul Peso 17 12 17 12 Ciudad Pars Pars Pars Pars

La clusula WHERE en un SELECT de una reunin puede incluir otras condiciones adems de la condicin de la reunin. 6.3.4 Recuperacin de campos especficos de una reunin.

Obtener todas las combinaciones de un nmero proveedor/nmero de parte tales que el proveedor y la parte en cuestin estn cosituados SELECT S.S# , P.P# FROM S, P WHERE S.CIUDAD = P.CIUDAD; Resultado: S# S1 S1 S1 S2 S2 S3 S3 S4 S4 S4 P P1 P4 P6 P2 P5 P2 P5 P1 P4 P6

Desde luego tambin es posible seleccionar slo los campos especificados de una reunin, en vez de seleccionarlos todos por fuerza. 6.3.5 Reunin de tres tablas.

Obtener todas las parejas de nombres de ciudad tales que un proveedor situado en la primera ciudad suministre una parte almacenada en la segunda ciudad. Por ejemplo, el proveedor S1 suministra la parte P1; el proveedor S1 est situado en Londres, y la parte P1 se almacena en Londres; por lo tanto, (Londres, Londres) es una pareja de ciudades en el resultado. SELECT DISTINCT S.CIUDAD, P.CIUDAD FROM S, SP, P WHERE S.S# = SP.S#

AND SP.P# = P.P#;

Resultado S. CIUDAD P.CIUDAD Londres Londres Londres Pars Londres Roma Pars Londres Pars Pars No hay un limite intrnseco para el nmero de tablas que se pueden juntar. Advirtase que se uso DISTINCT (distinto) en el ejemplo con el objeto de eliminar las parejas repetidas. 6.3.6 Reunin de una tabla consigo misma

Obtener todas las parejas de nmeros de proveedor tales que dos proveedores en cuestin estn cosituados. SELECT PRIMERA.S#, SEGUNDA.S# FROM S.PRIMERA, S.SEGUNDA WHERE PRIMERA.CIUDAD = SEGUNDA.CIUDAD AND PRIMERA.S# < SEGUNDA.S# Resultado: S# S1 S2 S S4 S3

Esta consulta implica una reunin de la tabla S consigo misma ( con base en igualdad de ciudades) segn se explica enseguida. Supongamos por un momento que tenemos dos copias separadas de la tabla S, la primera y la segunda. Entonces, la lgica de la consulta ser la siguiente: necesitamos poder examinar todas las parejas posibles de filas de proveedores, una de la primera copia de S y la otra de la segunda, y extraer los dos nmeros de proveedor de una de esas parejas de filas y slo si los valores de ciudad son iguales. Por tanto, necesitamos poder hacer referencia a dos filas de proveedor al mismo tiempo. Para distinguir entre las dos referencias, introducimos las variables de recorrido arbitrarias primera y segunda, cada una de las cuales recorre la tabla S. En todo momento PRIMERA representa alguna fila de la primera copia de, y SEGUNDA representa alguna fila de la segunda copia. El resultado de la consulta se obtiene examinando todas la posibles parejas de valores PRIMERA/SEGUNDA y probando la condicin WHERE en cada caso. Nota: el propsito de la condicin PIMERA.S# < SEGUNDA.S# es doble: a) Elimina las parejas de los nmeros de proveedor de la forma (x,x) b) Garantiza la aparicin de slo una de las parejas (x,y) y (y,x). ste primer ejemplo que hemos visto en el cual ha sido necesario el empleo de variables de recorrido. Sin embargo, nunca es errneo introducir tales variables, aun cuando no sea indispensable su empleo, y en ocasiones puede hacer ms clara la proposicin. 6.4 FUNCIONES AGREGADAS

Aunque es bastante poderosa en muchos aspectos la proposicin SELECT tal como se ha descrito hasta ahora resulta inadecuada para muchos problemas prcticos. Por ejemplo, aun una consulta tan sencilla como Cuantos proveedores hay? No puede expresarse empleando las construcciones utilizadas hasta ahora. Por tanto, SQL ofrece una serie de funciones agregadas especiales para ampliar su capacidad bsica de recuperacin de informacin. Estas funciones son COUNT(cuenta), SUM (suma), AVG (promedio), MAX (mximo), MIN (mnimo). Sin tomar en cuenta el caso especial de COUNT (*) (vase lo siguiente), cada una de las funciones trabaja sobre el total de valores en una columna de alguna tabla, quiz una tabla derivada, es decir, una tabla construida como resultado de alguna consulta y produce un solo valor como resultado segn estas definiciones: COUNT - nmero de valores en la columna SUM - suma de los valores de la columna AVG - promedio de valores de la columna MAX - valor ms grande de la columna MIN - valor ms pequeo de la columna En el caso de SUM y AVG la columna debe contener valores numricos. En general, el argumento de la funcin puede ir precedido de manera opcional por la palabra clave DISTINC para indicar que los valores repetidos deben eliminarse antes de que se aplique la funcin. En el caso de MAX y MIN, empero, DISTINCT sale sobrando y no tiene efecto alguno. En el caso de COUNT, es necesario especificar DISTINCT; se incluye la funcin especial COUNT (*), - no se permite DISTINCT para contar todas las filas de una tabla sin eliminacin de duplicados. Si hay nulos en la columna del argumento, se eliminarn antes de aplicarse la funcin, se especifique o no la palabra clave DISTINCT (excepto en el caso de COUNT (*), donde los valores nulos se manejan igual que los no nulos). Si el argumento es un conjunto vaco, COUNT devuelve el valor de cero; las dems funciones devuelven el valor nulo. 6.4.1 Funcin de agregados en la Clusula SELECT

Obtener el nmero total de proveedores. SELECT COUNT (*) FROM S Resultado 5

Obsrvese que el resultado en una tabla, con una fila y una columna (sin nombre) y contiene un solo valor escalar 5. 6.4.2 Funcin de agregados en la Clusula SELECT, con DISTINCT

Obtener el nmero total de proveedores que suministran partes en la actualidad. SELECT COUNT (DISTINCT S#)

FROM

SP;

Resultado: 4 6.4.3 funcin de agregados en la clusula SELECT, con una condicin obtener el nmero de envos de la parte P2 SELECT COUNT (*) FROM SP WHERE P# = P2 ; Resultado 6.4.4 4

funcin de agregados en la clusula SELECT, con una condicin

obtener la cantidad suministrada de la parte P2 SELECT SUM (CANT) FROM SP WHERE P# = P2; Resultado 6.4.5 ------1000

Empleo de GROUP BY (agrupar por)

El ejemplo 6.4.4 mostr cmo puede calcularse la cantidad total suministrada de una parte especifica. Pero vamos a suponer que deseamos calcular la cantidad total suministrada de cada parte: es decir, para cada parte suministrada, obtener el nmero de parte y la cantidad total enviada de esa parte. SELECT P# , SUM (CANT) FROM SP GROUP BY P#; Resultado: P# P1 P2 P3 P4 P5 P6 -----600 1000 400 500 500 100

Explicacin: el operador GROUP BY reorganiza en el sentido lgico la tabla representada por la clusula FROM formando particiones o grupos, de manera que dentro de un grupo dado todas las filas tengan el mismo valor en el campo de GROUP BY. (Desde luego, tal agrupamiento es meramente conceptual; la tabla no se reorganiza en la base de datos) En el ejemplo, la tabla SP se agrupa de manera tal que

un grupo contiene todas las filas de la parte P1, otro contiene todas las filas de la parte P2, etctera. En seguida se aplica la clusula SELECT a cada grupo de la tabla dividida ( y no a cada fila de la tabla original) cada expresin en la clusula SELECT debe producir un solo valor por grupo; es decir, puede ser el campo de GROUP BY mismo ( o quiz alguna expresin aritmtica que implique a ese campo), o un literal, o una funcin como SUM, la cual opera sobre todos los valores de un campo dado entero de un grupo y los reduce a un solo valor. Advirtase que GROUP BY no implica ORDER BY (ordenar por); si queremos presentar el resultado del ejemplo anterior ordenado por P# , deberemos especificar tambin la clusula ORDER BY P# ( despus de la clusula GROUP BY). Una tabla se puede agrupar segn cualquier combinacin de sus campos. En la seccin 6.7 se presenta un ejemplo de la agrupacin segn ms de un campo. 6.4.6 Empleo de HAVING (con)

Obtener los nmeros de todas las partes suministradas por ms de un proveedor. SELECT P# FROM SP GROUP BY P# HAVING COUNT(*) > 1; Resultado P# P1 P2 P4 P5

HAVING es a los grupos lo que WHERE es a las filas ( si se especifica HAVING, deber haberse especificado tambin GROUP BY). En otras palabras HAVING (con) sirve para eliminar grupos de la misma manera como WHERE (donde) sirve para eliminar filas. Las expresiones en una clusula HAVING deben producir un solo valor por grupo. 6.5 CARACTERISTICAS AVANZADAS

En esta seccin ilustraremos diversas caractersticas de la proposicin SELECT. A falta de un trmino mejor, llamaremos avanzadas a esas caractersticas, aunque en realidad no son ms complejas que algunos de los conceptos ya analizados en las ultimas tres secciones: de hecho algunas de ellas, - sobre todo EXISTS (vanse los ejemplos 6.5.7 a 6.5.10) son fundamentales; con todo, quiz se les encuentre con menor frecuencia en la prctica que las caractersticas analizadas en las secciones 6.2 a 6.4. por tal motivo, el lector puede optar por dejar a un lado esta seccin en una primera lectura. 6.5.1 recuperacin de datos con LIKE (como)

Obtener todas las partes cuyos nombres comiencen con la letra B. SELECT P.*

FROM P WHERE P.NOMBRE LIKE B%; Resultado: P# P3 P4 PNOMBRE Birlo Birlo COLOR azul rojo PESO CIUDAD 17 Roma 14 Londres

En general, una condicin LIKE (como) adopta la forma Columna LIKE literal-de-cadena Donde columna debe designar una columna de tipo de cadena ( CHAR o VARCHAR o GRAPHIC o VARGRAPHIC). Para un registro dado, la condicin se cumple si el valor dentro de la columna designada sigue el patrn especificado con literal. Los caracteres dentro de literal se interpretan de esta manera: El carcter _ (subrayado) representa cualquier carcter individual. El carcter % ( por ciento) representa cualquier secuencia de n caracteres (donde n puede ser cero) Todos los dems caracteres se representan por si mismos.

En el ejemplo, entonces, la proposicin SELECT extraer registros de la tabla P en los cuales el valor de PNOMBRE comience con la letra B seguida de cualquier secuencia de cero o ms caracteres. He aqu algunos ejemplos ms de LIKE ( y su opuesto, NOT LIKE (diferente de)); DOMICILIO LIKE %LIMA%- Se cumplir si domicilio contiene la cadena LIMA En cualquier posicin. S# LIKE S_ - Se cumplir si S# tiene una longitud de tres caracteres Y el primero es una S PNOMBRE LIKE %c___ - Se cumplir si PNOMBRE tiene una longitud de cuatro o ms caracteres y el tercero antes del ultimo es una c. CIUDAD NOT LIKE %E% - Se cumplir si CIUDAD no tiene una E 6.5.2 Recuperacin de datos que incluyen NULL (nulo)

Vamos a suponer para este ejemplo que la situacin del proveedor S5 tiene un valor nulo, en vez de 30. Obtener los nmeros de los proveedores cuya situacin es mayor que 25. SELECT S# FROM S WHERE SITUACIN >25 Resultado: S# S3

El proveedor S5 no cumple la condicin. Como se menciono en la seccin 5.2, cuando al evaluar una condicin se compara un nulo con cualquier otro valor, sea cual

sea el operador de comparacin empleado, el resultado de la comparacin nunca se considera verdadero, an cuando el otro valor tambin sea nulo. En otras palabras si SITUACIN tiene un valor nulo, ninguna de las siguientes comparaciones resulta verdadera: SITUACIN >25 SITUACIN <= 25 SITUACIN = 25 SITUACIN <> 25 SITUACIN = NULL /* Esta sintaxis no es legal. Ver lo que sigue */ SITUACIN <> NULL /* sta tampoco */ Se incluye una condicin especial con la forma Nombre columna IS [ NOT] NULL Para detectar la presencia o ausencia de nulos. Por ejemplo: SELECT S# FROM S WHERE SITUACIN IS NULL Resultado: S# S5

La sintaxis SITUACION = NULL no esta permitida, por que nada, ni siquiera un nulo se considera igual a otro nulo. 6.5.3 Recuperacin de datos con subconsulta.

Obtener los nombres de los proveedores que suministran la parte P2 SELECT SNOMBRE FROM S WHERE S in ( SELECT S# FROM SP WHERE P# = P2 ); Resultado : SNOMBRE Salazar Jaimes Bernal Corona

Explicacin: una subconsulta es (en trminos informales) una expresin SELECT FROM GROUP BY HAVING anidada dentro de otra expresin del mismo tipo. Las subconsultas se utilizan por lo regular para representar el conjunto de valores en el cual se realizar una bsqueda mediante una condicin IN (en), como puede verse en el ejemplo. Para evaluar la consulta completa, el sistema evala primero la subconsulta anidada (por lo menos desde el punto de vista conceptual). Esa subconsulta produce como resultado el conjunto de nmeros de proveedor de los

proveedores que suministran la parte P2, o sea el conjunto (S1,S2,S3,S4). As, la consulta original equivale a esta otra consulta mas sencilla:

SELECT NOMBRE FROM S WHERE S# IN (S1, S2,S3, S4); La clusula WHERE esta en forma ms sencilla si cumple si y slo si S# tiene uno de los valores S1,S2,S3,S4; por lo tanto, el resultado final es el que se mostr antes. Advirtase, por cierto, que el problema original - obtener los nombres de los proveedores que suministran la parte P2 se puede expresar tambin como una consulta de reunin as: SELECT FROM WHERE AND S,S.NOMBRE S,SP S.S# = SP.S# SP.P# = P2;

Explicacin: la reunion y de S y SP con base en nmeros de proveedor se compone de una tabla de doce filas (una por cada fila de SP), en la cual cada fila se compone de la fila correspondiente de SP ampliada con los valores SNOMBRE, SITUACIN Y CIUDAD del proveedor identificado por el valor S# de esa fila. de estas doce filas, cuatro corresponden a la parte P2; de modo que el resultado final se obtiene extrayendo los valores SNOMBRE de esas cuatro filas. Las dos formulaciones de la consulta original una mediante subconsulta y la otra mediante reunin son igualmente correctas. La eleccin de una u otra ser cuestin slo del gusto del usuario (excepto que segn lo avanzado del optimizador del sistema una de las dos podra representar mejor desempeo; en un sistema ideal, desde luego, el usuario no tendra que preocuparse por ese tipo de consideraciones). 6.5.4 subconsulta con varios niveles de anidamiento

Obtener los nombres de los proveedores que suministren por lo menos una parte roja. SELECT SNOMBRE FROM S (WHERE S# IN SELECT S# FROM SP (WHERE P# FROM P WHERE COLOR =ROJO)); Resultado: SNOMBRE Salazar Jaimes Corona

Las subconsultas pueden estar anidadas a cualquier profundidad. Ejercicio: presentar una formulacin de reunin equivalente para esta consulta.

6.5.5

Subconsulta con operador de comparacin distinto de IN

Obtener los nmeros de los proveedores situados en la misma ciudad que el proveedor S1. SELECT S# FROM S WHERE CIUDAD = (SELECT CIUDAD FROM S WHERE S# = S1); Resultado: S# S1 S4

Si el usuario sabe que el resultado de una subconsulta determinada ser exactamente un valor, puede utilizar un operador de comparacin escalar sencillo (como 0,>,etctera) en vez del IN acostumbrado. 6.5.6 funcin de agregados en una subconsulta

obtener los nmeros de los proveedores cuya situacin sea menor que el valor mximo actual de situacin en la tabla 5. SELECT SNOMBRE FROM S WHERE SITUACION < (SELECT MAX (SITUACION) FROM S); Resultado: S# S1 S2 S4

6.5.7

consulta con EXISTS (existe).

Obtener los nombres de los proveedores que suministran la parte P2 ( igual que en el ejemplo 6.5.3) SELECT SNOMBRE FROM S WHERE EXISTS

(SELECT FROM SP WHERE S# = S.S# AND P# = P2); Explicacin: EXISTS (existe) representa aqu el cuantificador existencial, la expresin EXISTS ( SELECT FROM) da como resultado un valor verdadero si y slo si el resultado de evaluar la subconsulta SELECT FROM no es el conjunto vaco; en otras palabras, si y slo si existe un registro en la tabla FROM de ese SELECT FROM , advirtase cmo la condicin WHERE dentro de la expresin EXISTS hace referencia a la tabla FROM del nivel externo de la consulta; lo hace a travs de un nombre de columna calificado de esa manera explcita (S.S#, en el ejemplo). Para entender como funciona el ejemplo, considrese en orden cada valor SNOMBRE, y vase si hace que se cumpla la prueba de existencia. Vamos a suponer que el primer valor de SNOMBRE es Salazar ( de modo que el valor correspondiente de S# es S1). Esta vaco el conjunto de los registros SP en los cuales S# es igual a S1 y P# es igual a P2, de manera que Salazar deber ser uno de los valores extrados. Lo mismo hace con los valores de SNOMBRE. As pues, otra forma de enunciar la consulta podra ser: seleccionar nombres de proveedores tales que exista un envo que relacione esos proveedores con la parte P2. Aunque este ejemplo en particular solo ilustra otra manera de formular una subconsulta para un problema que ya sabemos como manejar (mediante una reunin o bien una subconsulta), la construccin EXISTS es en realidad una de las ms bsicas y generales de todo el lenguaje de SQL. (Advirtase en particular que cualquier consulta en la cual se utilice IN siempre podr utilizar a modo EXIST, lo opuesto, en cambio, no se cumple.) la forma negada, NOT EXISTS (no existe) es importante sobre todo en cierto tipo de consultas. 6.5.8 Consulta con NOT EXISTS

Obtener los nombres de los proveedores que suministren la parte P2 ( lo inverso al ejemplo anterior). SELECT SNOMBRE FROM S WHERE NOT EXISTS ( SELECT * FROM SP WHERE S# = S.S# AND P# = P2); Resultado SNOMBRE Aldana

Otra forma de enunciar la consulta es: Seleccionar nombres de los proveedores tales que no exista un envo que relacione a esos proveedores con la parte P2. Cabe sealar que esta consulta sera equivalente a otra expresada en trminos de la forma negada de IN, a saber: SELECT SNOMBRE

FROM S WHERE S# NOT IN (SELECT S FROM SP WHERE P# = P2); 6.5.9 Consulta con NOT EXISTS Obtener los nombres de los proveedores que suministren todas las partes SELECT SNOMBRE FROM S WHERE NOT EXISTS (SELECT * FROM P WHERE NOT EXIST (SELECT * FROM SP WHERE S# = S.S# AND P# = P.P#)); Resultado SNOMBRE Salazar

La consulta podra enunciarse tambin as: obtener los nombres de los proveedores tales que no exista una parte que no suministren. Advirtase que esta consulta no podra expresarse usando la forma negada de IN. 6.5.10 Consulta con NOT EXISTS. Obtener los nmeros de los proveedores que suministran por lo menos todas las partes suministradas por el proveedor S2. Una forma de encarar este problema ms bien complejo es descomponerlo en una serie de consultas ms simples y manejarlas una por una. As, podemos encontrar primero el conjunto de nmeros de parte de las partes suministradas por el proveedor S2; SELECT P# FROM SP WHERE S# = S2; Resultado: P# P1 P2

Si utilizamos CREATE TABLE e INSERT ( lo cual analiza en forma detallada la siguiente seccin), es posible guardar este resultado en una tabla de la base de datos digamos la tabla TEMP, ahora podemos encontrar el conjunto de nmeros de proveedores que suministran todas las partes incluidas en TEMP.

SELECT DISTINCT S# FROM SP SPX WHERE NOT EXISTS (SELECT * FROM TEMP WHERE NOT EXISTS (SELECTS * FROM SP SPY WHERE SPY.S# = SPX.S# AND SPY.P# = TEMP.P#)); Resultado: S# S1 S2

Puede notarse que esta consulta difiere de la del ejemplo 6.5.9 en la necesidad de utilizar por lo menos una variable de recorrido explcita, pues estamos extrayendo valores de S# de la tabla SP y no valores de SNOMBRE de la tabla S y por esta razn es preciso poder hacer dos referencias simultneas pero distintas a la tabla SP. Ahora ya podemos desechar la tabla TEMP. Muchas veces es conveniente manejar consultas complejas con ste mtodo de paso por paso, pues se facilita la comprensin. Pero desde luego es posible tambin expresar toda la consulta como una sola proposicin SELECT, con lo cual resulta del todo innecesaria la tabla TEMP. SELECT DISTINCT S# FROM SP SPX WHERE NOT EXISTS ( SELECT * WHERE S# = P2 AND NOT EXISTS ( SELECT * FROM SP SPZ WHERE SPZ.S# = SPX.S# AND SPZ.P# = SPY.P#)); 6.5.11 Consulta con unin Obtener todos los nmeros de las partes que pesen ms de 16 libras, o sean suministradas por el proveedor P2 ( o las dos cosas) SELECT P# FROM P WHERE PESO>16 UNION

SELECT P# FROM SP WHERE S# = P2; Resultado -----P1 P2 P3 P6

UNION es el operador de unin de la teora de conjuntos tradicional. En otras palabras, A UNION B ( donde A y B son conjuntos) es el conjunto de todos los objetos de x tales que x es miembro de A o x es miembro e B ( o las dos cosas). Las filas repetidas siempre se eliminan del resultado de una UNION.* 6.6 OPERACIONES DE ACTUALIZACIN

El lenguaje de manipulacin de SQL, incluye tres operaciones de actualizacin: UPDATE(actualizar en el sentido de alterar o modificar), DELETE (eliminar) e INSERT (insertar). UPDATE (actualizar) Formato general: UPDATE Tabla SET campo = expresin-escalar [campo = expresin-escalar] WHERE [condicin]; Todos los registros de tabla que satisfagan condicin sern modificados de acuerdo con las asignaciones ( campo = expresin-escalar) de la clusula SET (establecer). 6.6.1 Modificacin de un solo registro.

Cambiar a amarillo el color de la parte P2, aumentar su peso en cinco e indicar que su ciudad es desconocida (NULL) UPDATE P SET COLOR=.amar PESO=PESO+5, CIUDAD= NULL WHERE P# = P2; Para cada uno de los registros que se van a modificar ( es decir, cada registro que satisface la condicin WHERE, o todos los registros si se omiten la clusula WHERE),

Las referencias en la clusula SET a campos dentro de ese registro representan los valores que tiene esos campos antes de ejecutarse cualquiera de las asignaciones de esa clusula SET. 6.6.2 Modificacin de varios registros.

Duplicar la situacin de todos los proveedores situados en Londres UPDATE S SET SITUACION = 2*SITUACIN WHERE CIUDAD = LONDRES; 6.6.3 Modificacin con subconsulta.

Poner en ceros la cantidad enviada por todos los proveedores de Londres. UPDATE SP SET CANT = 0 WHERE Londres = (SELECT CIUDAD FROM S WHERE S.S# = SP.S#); 6.6.4 Modificacin de varias tablas.

Cambiar el nmero de proveedor con S2 a S9 UPDATE SET WHERE UPDATE SET WHERE S S# = S9 S# = S2; SP S# = S9 S# = S2;

Como por definicin las operaciones UPDATE (y DELETE e INSERT) modifican la base de datos, existe siempre la posibilidad de alterar en alguna forma incorrecta i violar con ello la integridad de los datos. El ejemplo ilustra este punto: La primera posicin UPDATE (si fuera aceptada) hara inconsistente a la base de datos. Incluira algunos envos para los cuales no existira el proveedor correspondiente. Y permanecera en ese estado en tanto no se ejecutar la segunda proposicin UPDATE (en este ejemplo pasamos por alto el hecho de que, en la practica, DB2 rechazara de todos modos la primera modificacin, precisamente por este problema de integridad.) De hecho, el ejemplo ilustra un tipo muy especifico de violacin de la integridad, a saber, la violacin de la integridad referencial. La integridad referencial se analiza en forma detallada en el capitulo 12. DELETE (ELIMINAR) Formato general: DELETE

FROM TABLA { WHERE CONDICIN}; Se eliminaran todos los registros de TABLA que satisfagan CONDICION. 6.6.5 Eliminacin de un solo registro

Eliminar el proveedor S5. DELETE FROM S WHERE S# = S5; En general, la eliminacin de un proveedor puede llegar a provocara una violacin de la integridad referencial (si la base de datos incluye envos de ese proveedor; compares con el ejemplo 6.6.4). una vez ms, la integridad referencial se analiza en el capitulo 12. 6.6.6 Eliminacin de varios registros.

Eliminar todos los envos cuya cantidad sea mayor de 300. DELETE FROM SP WHERE CANT > 300; 6.6.7 Eliminacin de varios registros.

Eliminar todos los embarques. DELETE FROM SP; SP es todava una tabla conocida ( eliminar todos los registros no equivale a desechar (DROP) la tabla), pero ahora esta vaca. 6.6.8 Eliminacin con subconsulta.

Eliminar todos los envos de proveedores situados en Londres. DELETE FROM SP WHERE Londres = (SELECT CIUDAD FROM S WHERE S.S# = SP.S# ); INSERT (INSERTAR) Formato general:

INSERT INTO TABLA [(CAMPO[CAMPO])] VALUES (Literal[, literal]); O bien INSERT INTO TABLA [(campo[, campo])] Subconsulta; En el primer formato se inserta en TABLA una fila con los valores especificados en los campos especificados ( el isimo literal en la lista de literales corresponde al isimo campo en la lista de campos). En el segundo formato, se vala la subconsulta y se inserta una copia del resultado ( casi siempre varias filas) en TABLA; la isima columna de ese resultado corresponde a isimo campo en la lista de campos. En ambos casos, omitir la lista de campos equivale a especificar una lista con todos los campos de la tabla en orden de izquierda a derecha ( como en caso de SELECT *). 6.6.9 Insercin de un solo registro

Aadir la parte P7 (ciudad, Atenas, Peso, 24; nombre y color desconocidos por ahora) A la tabla P. INSERT INTO P (P#,CIUDAD,PESO) VALUES (P7,Atenas,24); Se crea un nuevo registro de parte con el nmero de parte, la ciudad y el peso especificados y con nulos en las posiciones del nombre y color. (suponemos, en este ejemplo, que estos campos no se definieron NOT NULL en la proposicin CREATE TABLE con la cual se cre la tabla P.) el orden de izquierda a derecha con el cual se nombrar los campos en la proposicin INSERT no es por fuerza el mismo con el que se especificaron el la proposicin CREATE TABLE (o ALTER TABLE). 6.6.10 Insercin de un solo registro, omitiendo nombres de campos. Aadir la parte P8 ( nombre, cadena, color, rosa, peso, 14, ciudad, Niza) A la tabla P INSERT INTO P VALUES ( P8 ,cadena, rosa, 14, Niza); Omitir la lista de campos equivale a especificar una lista con todos los campos de la tabla, en el orden de izquierda a derecha con el cual se definieron en la proposicin CREATE TABLE. Como en el caso de SELECT *, esta forma corta quiz sea conveniente en SQL interactivo, pero puede ser peligrosa en SQL embebido ( o sea,

SQL dentro de un programa de aplicacin) por que la lista de campos supuesta puede cambiar si el programa se religa y a cambiado entre tanto la definicin de la tabla.

6.6.11 Insercin de un solo registro. Insertar un nuevo envo con nmero de proveedor S20, nmero de parte P20 y cantidad 1000. INSERT INTO SP (S#, P#, CANT) VALUES ( S20, P20, 1000); Al igual que UPDATE y DELETE, INSERT puede provocar problemas de integridad referencial ( si no existen controles adecuados; Vase el capitulo 12). En el presente caso, DB2 rechazara el intento de insercin, por que no existe el proveedor S20 en la tabla S ni la parte P20 en la tabla. 6.6.12 Insercin de varios registros. Para cada parte suministrada, obtener el nmero de parte y la cantidad total suministrada, y guardar el resultado en la base de datos. CREATE TABLE TPMP ( P# CHAR (6) NOT NULL, CANTTOTAL INTEGER NOT NULL, PRIMARY KEY ( P#); CREATE UNIQUE INDEX XT ON TEMP ( P#); INSERT INTO TEMP ( P#, CANTTOTAL) SELECT P#, SUM (CANT) FROM SP GROUP PY P# Se ejecuta la proposicin SELECT, igual que una seleccin ordinaria, pero el resultado , en vez de presentarse al usuario, se copia a la tabla TEMP. Ahora el usuario puede hacer lo que desee con esa copia: consultarla, imprimirla y hasta modificarla; ninguna de esas operaciones afectara en absoluto los datos originales. Cuando ya no se necesite, la tabla TEMP podr desecharse. DROP TABLE TEMP; El ejemplo anterior es una ilustracin perfecta de la importancia de la propiedad de cerradura en los sistemas relacionales. El ejemplo funciona precisamente porque el resultado de una proposicin SELECT es otra tabla. No resultara si el resultado fuera algo distinto.

Por cierto, no es indispensable que la tabla objetivo este vaca antes de efectuar una insercin de varios registros, aunque s lo esta en el ejemplo anterior, si no esta vaca los nuevos registros simplemente se agregarn a los ya presentes.

6.7

COMENTARIOS FINALES.

Ya hemos presentado todas las caractersticas de la proposiciones de manipulacin de datos de SQL que pensamos ilustrar en este libro. En trminos especficos hemos descrito: La clusula SELECT ( seleccionar) bsica, incluyendo el empleo de DISTINC (distinto), literales, y expresiones escalares, y SELECT * La clusula FROM (de), incluyendo el empleo de variables de recorrido El empleo de ORDER BY (ordenar por) para ordenar la tabla de resultado La clusula WHERE (donde), incluyendo: - operaciones escalares de comparacion =,<>, >, <, <=, >= - condiciones de reunin - operadores booleanos AND,OR,NOT Las funciones de agregados COUNT(cuenta), SUM (suma), AVG (promedio), MAX(mximo), MIN (mnimo), y el empleo de la clusulas GROUP BY (agrupar por) y HAVING (con) Las condiciones especiales [NOT] LIKE([no] como e IS [NOT] NULL ([no] es nulo) El empleo de subconsultas y el operador de comparacin [NOT] IN ([no]) en) Empleo del cuantificador existencial EXISTS (existe) (sobre todo la forma negada NOT EXISTS (no existe)) El operador UNION (unin) Las proposiciones de actualizacin UPDATE (modificar), DELETE ( eliminar), e INSERT (insertar)

Cabe sealar que la existencia de slo cuatro proposiciones de DML en SQL es una de las razones de la relativa facilidad del empleo de ese lenguaje. Y el hecho de que slo haya cuatro operaciones de este tipo es una consecuencia de la sencillez de la estructura de datos relacional. Como se explico en el capitulo 4, toda la informacin de una base de datos relacionada se representa de la misma manera, a saber, como valores dispuestos de columnas dentro de filas pertenecientes a tablas. Como slo hay una forma de representar cualquier cosa, slo se requiere un operador para cada una de las cuatro funciones bsicas de manipulacin (recuperar, modificar, insertar, eliminar). En cambio en los sistemas basados en estructuras de datos ms complejas requieren en principio 4n operaciones de este tipo, donde n es el nmero de formas de representar datos en ese sistema. Por ejemplo en los sistema derivados de CODASYL, donde los datos se pueden representar ya sea como registros o como ligas entre registros, lo ms comn es encontrar una operacin STORE (almacenar) para crear un registro y una operacin CONNECT (conectar) para crear una liga; una operacin ERASE para eliminar un registro y una operacin DISCONNECT (desconectar) para eliminar una

liga,; una operacin MODIFY (modificar) para alterar un registro y una operacin RECONNECT (reconectar) para modificar una liga, Etc. Para concluir, presentamos un ejemplo muy rebuscado para ilustrar como pueden utilizarse muchas de las caractersticas de SQL analizadas en este capitulo. Tambien presentamos un algoritmo conceptual para evaluar una proposicin de este tipo. Advirtase que en cierto sentido SELECT es la ms fundamental de las cuatro operaciones de DML, pues las otras tres deben ir siempre precedidas al menos en forma implcita, si no explcita- por una seleccin apropiada. Por ejemplo, en el caso de DELETE el sistema debe ejecutar antes una seleccin implcita para localizar los datos que debe eliminar. Ejemplo: Para todas las partes rojas y azules tales que la cantidad total suministrada sea mayor o igual que 350 (excluyendo del total todos los envos cuyas cantidades sean menores o iguales a 200), obtener el nmero de parte, el peso en gramos, el color y la cantidad mxima suministrada de esa parte; y clasificar el resultado en orden descendente por nmero de parte dentro de un orden ascendente segn esa escala mxima. SELECT P.P#, peso en gramos=, P.PESO *454, P.COLOR, cant.mx.embarcada=, MAX (SP.CANT) FROM P, SP WHERE P.P# = SP.P# AND (P.COLOR= rojo OR P.COLOR = azul ) AND SP.CANT > 200 GROUP BY P.P# , P.PESO, P.COLOR HAVING SUM (CANT) >350 ORDER BY 6, P.P# DESC; Resultado: P# P1 P5 P3 peso en gramos = 5448 peso en gramos = 5448 peso en gramos = 7718 COLOR rojo cant. Mx enviada = 300 azul cant. Mx enviada = 400 azul cant. Mx enviada = 400

Debe entenderse que el algoritmo recin descrito se presenta como una explicacin puramente conceptual de la forma como se evala la proposicin SELECT (seleccionar). Sin duda es correcta, en cuanto a que se producir con certeza el resultado correcto; de hecho, puede tomarse como definicin de cual debe ser el resultado. No obstante si se le ejecutara en realidad, lo ms probable es que fuera bastante ineficiente. Por ejemplo, no sera conveniente, por razones de espacio de almacenamiento y tambin el tiempo de ejecucin, la construccin del producto cartesiano sugerida en el paso 1. Consideraciones como sta son precisamente las que justifican la necesidad de un optimizador de sistema relacionales. De hecho, el objetivo del optimizador puede definirse como encontrar un procedimiento que produzca el mismo resultado producido por el algoritmo conceptual antes descrito pero que sea ms eficiente en trminos de espacio o de tiempo ( o de ambos, si es posible).

Por ltimo, acerca del ejemplo de consulta en s: la proposicin SELECT mostrada es desde luego bastante compleja, pero pensemos en todo el trabajo que realiza. Un programa convencional para efectuar la misma tarea, escrito en el lenguaje de COBOL, podra ocupar con facilidad nueve pginas, en vez de solo nueve renglones, y la labor requerida para poner en funcionamiento ese programa sera bastante mayor que la implicada en la construccin de la versin de SQL mostrada. En la practica, por supuesto, la mayor parte de las consultas sern de todos modos ms sencillas que sta. Ejercicios. Todos los ejercicios utilizan la base de datos de proveedores, partes y proyectos (vanse los ejercicios del capitulo 5). En casi todos se pide al lector que escriba una proposicin o conjunto de proposiciones en SQL para la operacin indicada. Por conveniencia repetimos aqu la estructura de la base de datos. S ( S#, SNOMBRE, SITUACION, CIUDAD) P (P#, PNOMBRE, COLOR,PESO,CIUDAD) J (J#, JNOMBRE,CIUDAD) SPJ (S#, P#, J#, CANT) Dentro de cada subseccin, los ejercicios se presentan en orden aproximado de dificultad creciente. Se recomienda intentar al menos algunos de los ms difciles en cada grupo. Los nmeros 34 a40 son bastante difciles. Consultas sencillas: 6.1 Obtener los detalles completos de los proyectos. 6.2 Obtener los detalles completos de los proyectos de Londres 6.3 Obtener los nmeros de los proveedores que suministran partes al proyecto J1 , ordenados por el nmero del proveedor. 6.4 Obtener todos los envos en los cuales la cantidad est en el intervalo de 300 a 750 inclusive. 6.5 Obtener una lista de todas las combinaciones parte-color / parte-ciudad, eliminando todas las parejas color / ciudad repetidas. Reuniones. 6.6 Obtener todas las tripletas nmero de proveedor /nmero de parte/ nmero de proyecto tales que el proveedor, la parte y el proyecto indicados estn en la misma ciudad. 6.7 Obtener todas las tripletas nmero de proveedor /nmero de parte/ nmero de proyecto tales que el proveedor, la parte y el proyecto indicados no estn todos cosituados. 6.8 obtener todas las tripletas nmero de proveedor /nmero de parte/ nmero de proyecto tales que el proveedor, la parte y el proyecto indicados estn todos en diferente ciudad. 6.9 Obtener los nmeros de las partes suministradas por algn proveedor de Londres.

6.10 Obtener los nmeros de las partes suministradas por algn proveedor de Londres a un proyecto en Londres. 6.11 obtener todas las parejas de nombres de ciudades tales que un proveedor de a primera ciudad suministre partes a un proyecto en la segunda ciudad. 6.12 obtener los nmeros de las partes suministradas a un proyecto por un proveedor situado en la misma ciudad que en el proyecto. 6.13 obtener los nmeros de los proyectos a los cuales suministra partes por lo menos un proveedor situado en diferente ciudad. 6.14 obtener todas las parejas de nmeros de partes tales que algn proveedor suministre dos partes indicadas. FUNCIONES AGREGADAS 6.15 obtener el nmero total de proyectos a los cuales suministra partes el proveedor S1 6.16 obtener la cantidad total de la parte P1 suministrada por el proveedor S1 6.17 para cada parte suministrada a un proyecto, obtener el nmero de parte, el nmero de proyecto y la cantidad total correspondiente. 6.18 obtener los nmeros de las partes suministradas a algn proyecto tales que la cantidad promedio suministrada sea mayor que320. DIVERSAS 6.19 obtener todos los envos para los cuales la cantidad no sea nula 6.20 obtener nmero de proyecto y ciudades en los cuales la segunda letra del nombre de la ciudad sea una o. 6.21 obtener los nombres de los proyectos a los cuales suministra partes el proveedor S1 6.22 Obtener los colores de las partes suministradas por el proveedor S1 6.23 Obtener los nmeros de las partes suministradas a cualquier proyecto en Londres 6.24 Obtener los nmeros de los proyectos donde se utilice al menos una de las partes suministradas por el proveedor S1. 6.25 obtener los nmeros de los proveedores que suministren por lo menos unas de las partes suministradas por al menos uno de los proveedores que suministran por lo menos una parte roja. 6.26 obtener los nmeros de proveedores cuya situacin sea inferior a la del proveedor S1. 6.27 obtener los nmeros de los proyectos cuya ciudad sea la primera en la lista alfabtica de las ciudades donde hay proyectos. 6.28 Obtener los nmeros de los proyectos a los cuales se suministre la parte P1 en una cantidad promedio mayor que la cantidad mxima en la cual se suministra alguna parte al proyecto J1 6.29 Obtener los nmeros de los proveedores que suministren la parte P1 a algn proyecto en una cantidad mayor que la cantidad promedio enviada de la parte P1 para ese proyecto. EXISTS (existe) 6.30 Repetir el ejercicio 6.23 utilizando exists en la solucin. 6.31 repetir el ejercicio 6.24 utilizando exists en la solucin. 6.32 obtener los nmeros de los proyectos a los cuales no suministra ninguna parte roja ninguno de los proveedores de Londres. 6.33 Obtener los nmeros de los proyectos para los cuales S1 es el nico proveedor

6.34 Obtenr los nmeros de las partes suministradas a todos los proyectos en nombres. 6.35 Obtener los nmeros de los proveedores que suministren la misma parte a todos los proyectos. 6.36 Obtener los nmeros de los proyectos a los cuales se suministren por lo menos todas las partes suministradas por el proveedor S1. En los siguientes cuatro ejercicios (6.37 a 6.40) convertir la proporcin SELECT de SQL mostrada a su equivalente en espaol. 6.37 SELECT DISTINC J# FROM SPJ SPJX WHERE NOT EXISTS (SELECT * FROM SPJ SPJX WHERE SPJX.J# = SPJX.J# AND NOT EXISTS (SELECT * FROM SPJ SPJZ WHERE SPJZ.P# = SPJY.P# AND SPJZ.S# = S1 )); SELECT DISTINC J# FROM SPJ SPJX WHERE NOT EXISTS (SELECT * FROM SPJ SPJX WHERE EXISTS (SELECT * FROM SPJ SPJA WHERE SPJA.S# = S1 AND SPJA.P# = SPJY.P#) AND NOT EXISTS ( SELECT * FROM SPJ SPJB WHERE SPJB.S# = S1 AND SPJB.P# = SPJY.P# AND SPJB.J# = SPJX.J#)); 6.39 SELECT DISTINC J# FROM SPJ SPJX WHERE NOT EXISTS (SELECT * FROM SPJ SPJY WHERE EXISTS (SELECT * FROM SPJ SPJA WHERE SPJA.P# = SPJY.P# AND SPJA.J# = SPJX.J#)

6.38

AND NOT EXISTS (SELECT * FROM SPJ SPJB WHERE SPJB.S# = S1 AND SPJB.P# = SPJY.P# AND SPJB.J# = SPJX.J#)); 6.40 SELECT DISTINC J# FROM SPJ SPJX WHERE NOT EXISTS (SELECT * FROM SPJ SPJY WHERE EXISTS (SELECT * FROM SPJ SPJA WHERE SPJA.S# = SPJY.S# AND SPJA.P# IN (SELECT P# FROM P WHERE COLOR = rojo) AND NOT EXISTS (SELECT * FROM SPJ SPJB WHERE SPJB.S# = SPJY.S# AND SPJB.J# = SPJX.J#))); UNION 6.41 Construir una lista ordenada de todas las ciudades en las cuales este situado por lo menos un proveedor, una parte o un proyecto. 6.42 Mostrar el resultado de la siguiente seleccin: SELECT P.COLOR FROM P UNION SELECT P.COLOR FROM P. OPERACIONES DE ACTUALIZACION 6.43 Cambiar a gris el color de todas las partes rojas 6.44 Eliminar todos los proyectos para los cuales no haya envos. 6.45 Insertar un nuevo proveedor (S10) en la tabla S. El nombre y la ciudad son Salazar y Nueva York, respectivamente; la situacin no se conoce todava. 6.46 Construir una tabla con los nmeros de las partes suministradas ya sea por un proveedor de Londres o un proyecto en Londres. 6.47 Construir una tabla con los nmeros de los proyectos situados en Londres a los cuales suministren partes algn proveedor de Londres. RESPUESTA A EJERCICIOS SELECTOS.

Las siguientes soluciones no son por fuerza las nicas posibles. 6.1 SELECT J#, JNOMBRE, CIUDAD FROM J; 6.2 SELECT J#, JNOMBRE, CIUDAD FROM J WHERE CIUDAD = Londres; 6.3 SELECT DISTINC S# FROM SPJ WHERE J# = J1 ORDER BY S#; 6.4 SELECT S#, P#, J# CANT FROM SPJ WHERE CANT > = 300 AND CANT <= 750 6.5 SELECT DISTINC COLOR, CIUDAD FROM P; 6.6 SELECT S#, P#, J# FROM S, P, J WHERE S.CIUDAD=P.CIUDAD AND P.CIUDAD= J.CIUDAD; 6.7 SELECT S#, P#, J# FROM S,P,J WHERE NOT (S.CIUDAD = P.CIUDAD AND P.CIUDAD = J.CIUDAD ); 6.8 SELECT S#, P#, J# FROM P,J WHERE S.CIUDAD <> P.CIUDAD AND P.CIUDAD <> J.CIUDAD AND J.CIUDAD <> S.CIUDAD; 6.9 SELECT DISTINC FROM SPJ, S WHERE SPJ.S# = S.S# AND CIUDAD = LONDRES 6.10 SELECT DISTINC P* FROM SPJ, S, J WHERE SPJ. S# = S.S# AND SPJ.J# = J.J# AND S.CIUDAD = LONDRES

AND J.CIUDAD = LONDRES; 6.11 SELECT DISTINC S.CIUDAD, J.CIUDAD FROM S, SPJ, J WHERE S.S# SPJ.S# AND SPJ.J# = J.J#; 6.12 SELECT DISTINC P# FROM SPJ, S, J WHERE SPJ.S# = S.S# AND SPJ.J# = J.J# AND S.CIUDAD <> J.CIUDAD; 6.14 SELECT SPJX.P#, SPJY.P# FROM SPJX, SPJ, SPJY WHERE SPJX.S# = SPJY.S# AND SPJX.P# > SPJY.P#; 6.15 SELECT COUNT (DISTINC J#) FROM SPJ WHERE S# = S1; 6.16 SELECT SUM (CANT) FROM SPJ WHERE P# = P1 AND S# = S1; 6.17 SELECT P#, J#, SUM (CANT) FROM SPJ GRUOP BY P#, J#; 6.18 SELECT DISTINC P# FROM SPJ GROUP BY P#, J# HAVING AVG (CANT) > 320; 6.19 SELECT S#, P#, J#, CANT FROM SPJ WHERE CANT IS NOT NULL; 6.20 SELECT J#, CIUDAD FROM J WHERE CIUDAD LIKE _o%; 6.21 SELECT JNOMBRE FROM J WHERE J# (SELECT J# FROM SPJ WHERE S# = S1);

Você também pode gostar