informatica ii (ing. industrial) – segundo …15dejuniomnr.com.ar/blog/apunteca/ciclo...

27
1 INFORMATICA II (Ing. Industrial) – SEGUNDO CUATRIMESTRE 2009 – DIV. 51 – TEORIA UNIDADES 4 A 6 Ing. Fernando P. Guspí UNIDAD 4.- INTRODUCCION AL LENGUAJE SQL SQL (structured query language o lenguaje estructurado de consultas), es un lenguaje para el procesamiento de bases de datos relacionales, desarrollado paralelamente a la teoría de éstas. Desde su origen, ha experimentado sucesivas ampliaciones y normalizaciones (p. ej. la versión normalizada ANSI SQL), y en tal sentido se lo considera un lenguaje universal para el manejo de bases de datos relacionales. Todos los utilitarios lo incorporan, y también le agregan variantes no normalizadas que difieren ligeramente de uno a otro. Si se necesita, se puede combinar SQL con comandos propios del gestor, y estructuras de control del lenguaje anfitrión, de manera de producir programas integrados. Los comandos SQL se basan en las operaciones relacionales, y describen resultados más que los procedimientos para llegar a ellos. Por eso se suele decir que SQL es un metalenguaje. Creación, indexación y modificación de la estructura de tablas Ya vimos el comando SQL básico para crear una tabla: CREATE TABLE nombre (campo1 tipo1, campo2 tipo 2, ... ) A este comando se le pueden agregar cláusulas que establezcan que determinado campo o campos sean clave primaria o externa etc., pero la sintaxis no está normalizada. P. ej. para crear la tabla REPUESTOS NRO_PIEZA NRO_PROV DESCRIP PRECIO pidiendo al mismo tiempo que la clave primaria sea NRO_PIEZA, podemos hacer en FOX CREATE TABLE REPUESTOS (NRO_PIEZA N(4,0) PRIMARY KEY, NRO_PROV N(4,0), DESCRIP C(30), PRECIO N(7,2)) En cambio, en ACCESS, debemos emplear una sintaxis como la que sigue: CREATE TABLE REPUESTOS (NRO_PIEZA INT CONSTRAINT C1 PRIMARY KEY, NRO_PROV INT, DESCRIP TEXT(30), PRECIO FLOAT) Es decir, para definir una clave primaria, antes de PRIMARY KEY debemos colocar la palabra reservada CONSTRAINT (restricción), seguida de un nombre cualquiera que elegimos para identificar a la restricción (aquí hemos elegido C1). El nombre de la restricción lo utiliza el gestor en los mensajes de error. P. ej. “Se ha violado la restricción C1”). Si la clave primaria es compuesta, no se la debe declarar con cada campo, sino al final del comando, y aquí aparecen más diferencias entre gestores. P. ej. si en la tabla anterior queremos establecer como clave primaria la combinación de NRO_PIEZA y NRO_PROV, en FOX se las debe concatenar, asignando a la clave compuesta un nombre o TAG: CREATE TABLE REPUESTOS (NRO_PIEZA N(4,0), NRO_PROV N(4,0), DESCRIP C(30), PRECIO N(7,2), PRIMARY KEY STR(NRO_PIEZA)+ STR(NRO_PROV) TAG PPROV) En cambio, en ACCESS, no se usa TAG sino CONSTRAINT, y la combinación de campos va entre paréntesis:

Upload: trinhliem

Post on 03-Oct-2018

243 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

1

INFORMATICA II (Ing. Industrial) – SEGUNDO CUATRIMESTRE 2009 – DIV. 51 – TEORIA UNIDADES 4 A 6 Ing. Fernando P. GuspíUNIDAD 4.- INTRODUCCION AL LENGUAJE SQL

SQL (structured query language o lenguaje estructurado de consultas), es un lenguaje para el procesamiento de bases de datos relacionales, desarrollado paralelamente a la teoría de éstas. Desde su origen, ha experimentado sucesivas ampliaciones y normalizaciones (p. ej. la versión normalizada ANSI SQL), y en tal sentido se lo considera un lenguaje universal para el manejo de bases de datos relacionales. Todos los utilitarios lo incorporan, y también le agregan variantes no normalizadas que difieren ligeramente de uno a otro. Si se necesita, se puede combinar SQL con comandos propios del gestor, y estructuras de control del lenguaje anfitrión, de manera de producir programas integrados. Los comandos SQL se basan en las operaciones relacionales, y describen resultados más que los procedimientos para llegar a ellos. Por eso se suele decir que SQL es un metalenguaje.

Creación, indexación y modificación de la estructura de tablas

Ya vimos el comando SQL básico para crear una tabla:

CREATE TABLE nombre (campo1 tipo1, campo2 tipo 2, ... )

A este comando se le pueden agregar cláusulas que establezcan que determinado campo o campos sean clave primaria o externa etc., pero la sintaxis no está normalizada. P. ej. para crear la tabla

REPUESTOS NRO_PIEZA NRO_PROV DESCRIP PRECIO

pidiendo al mismo tiempo que la clave primaria sea NRO_PIEZA, podemos hacer en FOX

CREATE TABLE REPUESTOS (NRO_PIEZA N(4,0) PRIMARY KEY, NRO_PROV N(4,0), DESCRIP C(30), PRECIO N(7,2))

En cambio, en ACCESS, debemos emplear una sintaxis como la que sigue:

CREATE TABLE REPUESTOS (NRO_PIEZA INT CONSTRAINT C1 PRIMARY KEY, NRO_PROV INT, DESCRIP TEXT(30), PRECIO FLOAT)

Es decir, para definir una clave primaria, antes de PRIMARY KEY debemos colocar la palabra reservada CONSTRAINT (restricción), seguida de un nombre cualquiera que elegimos para identificar a la restricción (aquí hemos elegido C1). El nombre de la restricción lo utiliza el gestor en los mensajes de error. P. ej. “Se ha violado la restricción C1”).

Si la clave primaria es compuesta, no se la debe declarar con cada campo, sino al final del comando, y aquí aparecen más diferencias entre gestores. P. ej. si en la tabla anterior queremos establecer como clave primaria la combinación de NRO_PIEZA y NRO_PROV, en FOX se las debe concatenar, asignando a la clave compuesta un nombre o TAG:

CREATE TABLE REPUESTOS (NRO_PIEZA N(4,0), NRO_PROV N(4,0), DESCRIP C(30), PRECIO N(7,2), PRIMARY KEY STR(NRO_PIEZA)+ STR(NRO_PROV) TAG PPROV)

En cambio, en ACCESS, no se usa TAG sino CONSTRAINT, y la combinación de campos va entre paréntesis:

Page 2: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

2

CREATE TABLE REPUESTOS (NRO_PIEZA INT, NRO_PROV INT, DESCRIP TEXT(30), PRECIO FLOAT, CONSTRAINT PPROV PRIMARY KEY (NRO_PIEZA, NRO_PROV))

(en cualquier caso también sería válido declarar al final una clave primaria simple).

De la misma manera, una clave externa simple con referencia a otra tabla puede declararse junto al mismo campo. P. ej. si la clave primaria de REPUESTOS es NRO_PIEZA, y el campo NRO_PROV es clave externa con referencia a la tabla PROVEEDORES, la creación de la tabla en FOX se puede hacer con el comando:

CREATE TABLE REPUESTOS (NRO_PIEZA N(4,0) PRIMARY KEY, NRO_PROV N(4,0) REFERENCES PROVEEDORES, DESCRIP C(30), PRECIO N(7,2))

mientras que en ACCESS sería:

CREATE TABLE REPUESTOS (NRO_PIEZA INT CONSTRAINT C1 PRIMARY KEY, NRO_PROV INT CONSTRAINT C2 REFERENCES PROVEEDORES, DESCRIP TEXT(30), PRECIO FLOAT)

Desde luego, la tabla PROVEEDORES tiene que haber sido creada antes de REPUESTOS, si no, la clave externa quedaría sin referencia, y daría lugar a un error. Si la clave externa es compuesta, se debe declarar al final, precedida de las palabras FOREIGN KEY.

Una tabla se puede indexar respecto de su clave primaria o de cualquier otra clave. Para ello hay que crear un archivo índice mediante comandos no normalizados del tipo

CREATE INDEX nombre_indice ON nombre_tabla (campo1, campo2, ... )

P. ej.

CREATE INDEX IND1 ON REPUESTOS (NRO_PIEZA, NRO_PROV)

CREATE INDEX LEGAJO ON ALUMNOS (LEGAJO)

Se pueden agregar campos vacíos o nulos a una tabla existente, sin alterar los datos que ya contiene: ALTER TABLE nombre_tabla ADD (campo1 tipo1, campo2 tipo2, ... )

Los nuevos campos se agregan a la derecha de los ya existentes. Si un quiere agregarlos en el medio, deberá hacer luego una operación de proyección, que veremos más adelante.

También se pueden eliminar campos completos de una tabla, y los eventuales datos que hay en ese campo también se eliminan:

ALTER TABLE nombre_tabla DROP (campo1, campo2, ... )

El comando DROP TABLE nombre_tabla

elimina la tabla, siempre que no se viole la integridad referencial (p. ej. querer eliminar la tabla PROVEEDORES cuando hay registros en REPUESTOS que le hacen referencia). De la misma manera, el comando

Page 3: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

3

DROP INDEX nombre_indice ON nombre_tabla

elimina el índice correspondiente.

Reiteramos que estos comandos SQL no están totalmente normalizados, las versiones que hemos mostrado son de tipo genérico, y puede haber variantes que se verán con más detalle en la parte práctica, especialmente con referencia al uso de paréntesis, TAG y CONSTRAINT.

Operaciones de actualización

Sabemos que éstas son las operaciones de insertar, eliminar y modificar.InsertarEn SQL básico esta operación es bastante incómoda, pues sólo permite agregar de a un registro por vez, dando valores constantes a los campos. P. ej. en la tabla

ARTICULOSNRO_ART DESCRIP PRECIO 1324 LAPIZ 3.10 1533 GOMA 1.40

1.20

Queremos agregar un nuevo registro 1511 CUADERNO, sin ponerle precio. Tenemos que hacer:

INSERT INTO ARTICULOS (NRO_ART, DESCRIP) VALUES (1511, ‘CUADERNO’)

Siempre se inserta un registro completo, y los campos no mencionados quedan con valor NULL.

En SQL de FOX ésta es la única inserción posible. En cambio, en ACCESS, la descripción de los valores a insertar puede hacerse con otro comando SQL, pero esto no está normalizado.

Eliminar (DELETE) y modificar (UPDATE)

Estas operaciones las estudiaremos después de las operaciones de consulta.

Operaciones de consulta

Estas son las operaciones más importantes de SQL, donde se pone en juego toda su potencia, porque con comandos relativamente simples, basados en el álgebra relacional, se pueden resolver problemas bastante complejos.

El operador básico de toda operación de consulta es SELECT, que debe figurar al principio de la sentencia, y puede significar tanto selección como proyección o reunión.

En SQL no hay tabla activa, ni mucho menos registro activo. Todos los comandos son globales, y deben incluir los nombres de las tablas que intervienen. El gestor las abre o cierra a medida que lo necesita.

SelecciónLa operación relacional σ (relacion) expresion_logica

se escribe en SQL

SELECT * FROM tabla WHERE expresion_logica

Page 4: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

4

El * después de SELECT es una forma abreviada de representar a todos los campos de la tabla, que es lo que necesita la operación de selección. P. ej.

SELECT * FROM PRODUCTOS WHERE PAIS=’A’ AND COD_PROD < 200

A partir de la tabla PRODUCTOS, este comando forma una nueva relación, con todos los campos, de la original, pero tomando sólo los registros en que PAIS = ’A’ y COD_PROD <= 200. En la práctica, cuando el comando es emitido desde un gestor, se despliega una ventana donde se visualiza la relación resultante, pero sin que la misma quede almacenada en ningún lado.

ProyecciónLa operación relacional Π atributo1, atributo2, ... (relacion)

se escribe en SQL

SELECT campo1, campo2, ... FROM tabla

y se puede combinar con selección agregándole una cláusula WHERE seguida de una expresión lógica.

SELECT campo1, campo2, ... FROM tabla WHERE expresion_logica

P. ej.SELECT LEGAJO, NOMBRE FROM ALUMNOS WHERE LEGAJO >=’M’ AND LEGAJO <’N’ (muestra el legajo y el nombre de los alumnos cuyo apellido comienza con ‘M’).

Asignación del resultadoLa forma de indicar que el resultado de una operación relacional debe almacenarse en una nueva tabla no está totalmente normalizada. El operador de asignación es INTO nombre_nueva_tabla, y debe incluirse en el comando SQL, generalmente antes del FROM, aunque p. ej. en FOX también se puede colocar después, antes del WHERE. El nombre de la nueva tabla puede ser cualquiera. Si no existe, el gestor la crea, y si existe pregunta si se quiere sobreeescribir. De todos modos, lo que hay que tener cuidado en FOX es anteponer la palabra TABLE al nombre del resultado, porque si no, lo grabaría en un archivo de texto. Ejemplo: A partir de una tabla

EXAMENES LEGAJO ASIGNAT FECHA_EXAMEN NOTA

en la cual aparecen resultados de exámenes, queremos generar una nueva tabla APROBAD, que contenga solamente el legajo y la asignatura de los alumnos aprobados. En SQL de ACCESS resolvemos el problema así:

SELECT LEGAJO, ASIGNAT INTO APROBAD FROM EXAMENES WHERE NOTA >= 6

En cambio, en SQL de FOX, la sintaxis cambiaría a SELECT LEGAJO, ASIGNAT INTO TABLE APROBAD; FROM EXAMENES; WHERE NOTA >= 6

Page 5: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

5

o bien

SELECT LEGAJO, ASIGNAT FROM EXAMENES; INTO TABLE APROBAD; WHERE NOTA >= 6

El punto y coma que se coloca en FOX (no en ACCESS) al final del renglón, indica que el comando continúa en la línea siguiente (al revés de algunos lenguajes, donde el punto y coma separa sentencias). En los ejemplos sucesivos omitiremos el punto y coma.

Es importante observar que, cualquiera sea el utilitario empleado, la nueva tabla no conserva las restricciones de las originales, y en particular, no posee clave primaria ni claves externas. Si se las quiere redefinir, debe hacerse con comandos ALTER TABLE.

En FOX, un comando SQL puede emitirse interactivamente y ejecutarse inmediatamente desde la ventana de comandos. La ejecución puede repetirse buscando el comando hacia atrás en la ventana, pero para conservarlo después de la sesión, debe guardarse en un programa.

En ACCESS, los comandos SQL pertenecen a una categoría especial llamada CONSULTAS, donde cada consulta tiene un nombre propio, y contiene un único comando SQL. Si se desea ejecutar secuencialmente varios comandos SQL, se puede recurrir a las MACROS, pero para combinar comandos con estructuras de control, hay que emplear programación VISUAL BASIC mediante formularios o módulos.

ReuniónEl producto cartesiano entre dos tablas, A y B, se hace así en SQL:

SELECT * FROM A, B

La reunión con alguna condición se expresa como

SELECT * FROM A, B WHERE expresión_lógica

La condición puede ser una igualdad de campos, y en ese caso se habla de una equirreunión. La reunión natural, o sea cuando se elimina uno de los campos repetidos, no se ejecuta automáticamente, y hay que detallar los campos como en una proyección, salvo en aquellos gestores que poseen el operador no normalizado NATURAL JOIN.

Ejemplo: Sean las tablas

VEHICULOSMARCA COMBUSTIBLE

FORD NAFTA SUPERFIAT GASOILFIAT NAFTA COMUNPEUGEOT GAS

Qué resultado produce el siguiente comando SQL?

SELECT MARCA, COMBUSTIBLE, PRECIO FROM VEHICULOS, COSTOS WHERE COMBUSTIBLE=COMB

COSTOSCOMB PRECIO

NAFTA ESPECIAL 3.90NAFTA SUPER 3.50GASOIL 3.00GAS 1.20

Page 6: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

6

MARCA COMBUSTIBLE PRECIOFORD NAFTA SUPER 3.50 FIAT GASOIL 3.00PEUGEOT GAS 1.20

sería una reunión natural.

Reuniones externas izquierda y derecha

La sintaxis de estas operaciones tiene la siguiente forma:

SELECT campo1, campo2, ... FROM tabla1 LEFT JOIN (o RIGHT JOIN) tabla2 ON expr_lógicaP. ej. el comando SELECT MARCA, COMBUSTIBLE, PRECIO FROM VEHICULOS LEFT JOIN COSTOS ON COMBUSTIBLE = COMB

produce el resultadoMARCA COMBUSTIBLE PRECIO

FORD NAFTA SUPER 3.50 1FIAT GASOIL 3.00

PEUGEOT GAS 1.20FIAT NAFTA COMUN

donde los registros podrían aparecer en cualquier orden. Igualmente

SELECT MARCA, COMBUSTIBLE, PRECIO FROM VEHICULOS RIGHT JOIN COSTOS ON COMBUSTIBLE = COMB

da como resultado MARCA COMBUSTIBLE PRECIO

FORD NAFTA SUPER 3.50FIAT GASOIL 3.00PEUGEOT GAS 1.20

NAFTA ESPECIAL 3.90

UniónConsideremos dos tablas:

CLIENTES NOMBRE LOCALIDAD DESCUENTO

EL SAUCE MACIEL 20 JUAN GOMEZ ROSARIO 10 IMPERIAL CORDOBA 30

Queremos hacer la unión de los campos NOMBRE y LOCALIDAD de las dos tablas

SELECT NOMBRE, LOCALIDAD FROM CLIENTES UNION SELECT * FROM PROVEEDORES

PROVEEDORESNOMBRE LOCALIDAD

ATLANTA AVELLANEDAIMPERIAL CORDOBAIMPERIAL FIRMAT

Page 7: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

7

NOMBRE LOCALIDADEL SAUCE MACIELJUAN GOMEZ ROSARIOIMPERIAL CORDOBAATLANTA AVELLANEDAIMPERIAL FIRMAT

Uso de alias y expresionesEn las reuniones, cuando los nombres de los campos en dos tablas coinciden, hay que anteponerles cada vez el nombre de la tabla de donde provienen, seguido de punto. P. ej.

SELECT CLIENTES.NOMBRE, PROVEEDORES.LOCALIDAD FROM CLIENTES, PROVEEDORES WHERE CLIENTES.NOMBRE = PROVEEDORES.NOMBRE

NOMBRE LOCALIDADIMPERIAL CORDOBAIMPERIAL FIRMAT

Esto resulta incómodo cuando los nombres de las tablas son largos, y se repiten muchas veces. Entonces, en vez del nombre verdadero, se puede emplear un alias más corto, de la siguiente forma:

SELECT A.NOMBRE, B.LOCALIDAD FROM CLIENTES A, PROVEEDORES B WHERE A.NOMBRE = B.NOMBRE

También se puede cambiar por un alias el nombre de cualquier campo de la tabla de salida. P. ej.

SELECT A.NOMBRE AS EMPRESA, B.LOCALIDAD AS DOMICILIO INTO [TABLE] COMUN FROM CLIENTES A, PROVEEDORES B WHERE A.NOMBRE = B.NOMBRE AND A.LOCALIDAD = B.LOCALIDAD

COMUNEMPRESA DOMICILIO

IMPERIAL CORDOBA

En un comando SELECT, se pueden incluir nuevos campos que contengan constantes o expresiones relacionadas con cada registro de las tablas que se procesan. P. ej.

SELECT NOMBRE, DESCUENTO / 2 AS TASA FROM CLIENTES

NOMBRE TASAEL SAUCE 10JUAN GOMEZ 5IMPERIAL 15

Otro ejemplo:

SELECT NOMBRE, ‘SI’ AS MAYORISTA FROM CLIENTES WHERE DESCUENTO >= 20

Page 8: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

8

UNION SELECT NOMBRE, ‘NO’ FROM CLIENTES WHERE DESCUENTO < 20

NOMBRE MAYORISTAEL SAUCE SIIMPERIAL SI JUAN GOMEZ NO

El alias MAYORISTA sólo se declara con el primer operando de la unión. Los nombres de campo del segundo operando no interesan, basta que sean del mismo tipo que los del primero. Este ejemplo da una muestra de la potencia de SQL para resolver un problema, y pone de manifiesto la necesidad de pensar las soluciones en términos de las operaciones relacionales.

Ordenamiento de tablas

El modelo relacional, y el lenguaje SQL no reconocen ningún orden lógico entre las tuplas o registros de una tabla. No hay primer registro, ni segundo, ni último. Sin embargo, en el almacenamiento siempre hay un orden físico, que corresponde al número relativo de registro en el archivo directo que contiene los datos de la tabla. Si bien los utilitarios en sus comandos propios (GO n, SKIP, etc.) tienen en cuenta ese orden, en SQL esto no se puede hacer, porque no es un lenguaje orientado al registro. Todos sus comandos son globales.Lo que sí se puede hacer en SQL es presentar los resultados de una consulta en un orden determinado, de acuerdo a un campo o combinación de campos. La cláusula que se agrega en una consulta es

ORDER BY campo1 [DESC], campo2 [DESC], ...

y debe colocarse al final del comando, después de WHERE. P. ej.

SELECT * FROM VEHICULOS ORDER BY MARCA, COMBUSTIBLE DESC

Este comando muestra la tabla VEHICULOS ordenando alfabéticamente los registros primero por marca. Cuando la marca se repite, los ordena por combustible, pero en forma descendente [DESC].

MARCA COMBUSTIBLEFIAT NAFTA COMUNFIAT GASOILFORD NAFTA SUPERPEUGEOT GAS

Si el resultado de una consulta con ORDER BY se guarda en otra tabla mediante cláusula INTO, la nueva tabla queda físicamente ordenada.

Funciones de agregado

Son funciones que permiten contar, promediar, etc. los valores de un mismo campo o columna de una tabla, es decir operaciones que se realizan en sentido vertical. Coinciden con las que ya se han empleado en programación, y las más usuales son:

COUNT o CNT contar SUM sumar AVG (average) promediar MAX máximo MIN mínimo

Page 9: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

9

Estas funciones devuelven como resultado un dato simple, que puede visualizarse en la pantalla o almacenarse en un campo o una variable para uso posterior, pero esto ya depende del gestor. En general, las funciones de agregado ignoran los registros con valores nulos. No obstante, la expresión COUNT (*) sirve para contar todos los registrosEjemplo: VENTAS

ARTICULO PRECIO IMPORTECUADERNOLAPIZ

6.50 130.00LAPIZ 3.10 31.00GOMA 1.40 70.00BLOCK 8.50

SELECT COUNT (*) FROM VENTAS (Resultado 4) SELECT COUNT (IMPORTE) FROM VENTAS (Resultado 3) SELECT AVG (IMPORTE) FROM VENTAS WHERE PRECIO>2 (Resultado 80.50) (promedia 2 valores, el nulo no lo tiene en cuenta) SELECT MIN (COMBUSTIBLE) FROM VEHICULOS (Resultado 'GAS')

Qué artículo o artículos tiene el máximo precio?Aquí hay que calcular primero el precio máximo, y luego listar los artículos que tienen ese precio. Para resolver el problema mediante dos comandos, habría que guardar el precio máximo en una variable: SELECT MAX (PRECIO) INTO ARRAY A FROM VENTAS SELECT * FROM VENTAS WHERE PRECIO = A

FOX admite esta combinación, conviniendo que aquí ARRAY significa variable simple. ACCESS, en cambio, no permite emplear variables en los comandos SQL (salvo que se les ingrese un valor en el momento). De todos modos hay una forma más general de resolver el problema, tanto en ACCESS como en FOX, que es mediante una subconsulta. El tema subconsultas se desarrolla en la próxima unidad, pero la presente subconsulta es sencilla de entender:

SELECT * FROM VENTAS WHERE PRECIO = (SELECT MAX (PRECIO) FROM VENTAS)

Continuación del tema Operaciones de actualización

EliminarEl comando DELETE FROM nombre_tabla WHERE condicion

elimina de la tabla los registros que cumplen la condición (en FOX, en realidad, sólo los borra lógicamente, o sea los marca como eliminados). P. ej.

DELETE FROM VEHICULOS WHERE COMBUSTIBLE = 'GASOIL'

El comando señala error si hay claves externas de otras tablas que apuntan a los registros a eliminar.

Modificar UPDATE nombre_tabla SET nombre_campo = expresion WHERE condicion

P. ej.

Page 10: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

10

UPDATE CLIENTES SET DESCUENTO = DESCUENTO + 5 WHERE LOCALIDAD = 'ROSARIO'El comando no se ejecuta si se violan las restricciones de la tabla.

Empleo de índices en SQL

Vimos que en SQL se pueden crear índices, pero ningún comando posterior hace referencia explícita a ellos. Esto no significa que no se usen. Al abrir la tabla, el gestor se fija primero si está indexada, y si lo está aprovecha sus ventajas. Si no lo está, puede operar secuencialmente, o bien crear índices para uso interno, que luego no quedan grabados. Es una muestra de la potencia de SQL, pero de todos modos conviene indexar las tablas que sean necesarias, para evitar trabajo extra al gestor.Ejemplos adicionales de resolución

Ejemplo 1En una localidad, se miden día a día las temperaturas mínima y máxima registradas, y se crea una tabla TEMPERATURAS

DIA TMIN TMAX01/05/2007 10 2202/05/2007 9 2203/05/2007 8 1804/05/200|7 20 7.............. ... ...

(se subraya la clave primaria)

a) Agregar a la tabla un nuevo campo TMED que contenga la temperatura promedio entre la mínima y la máxima, redondeada a un valor entero. Verificar también si hay registros en que por error la temperatura mínima y la máxima aparecen intercambiadas, y corregir esos errores.

Este problema podría resolverse por programación ordinaria, recorriendo la tabla registro por registro, y empleando variables de memoria intercambiar los datos. Sin embargo, trabajando en SQL, sólo se pueden ejecutar comandos globales y no se utilizan variables. Veamos cómo se puede aprovechar el campo TMED para contener valores auxiliares, antes de asignarle los datos definitivos. ALTER TABLE TEMPERATURAS ADD TMED N(3,0) UPDATE TEMPERATURAS SET TMED = TMAX (copia TMAX en TMED)

UPDATE TEMPERATURAS SET TMAX = TMIN WHERE TMED < TMIN (actualiza TMAX si está cambiada)

UPDATE TEMPERATURAS SET TMIN = TMED WHERE TMED < TMIN (actualiza TMIN)

UPDATE TEMPERATURAS SET TMED = (TMIN + TMAX) / 2 (carga el promedio)

La tabla resultante queda así: TEMPERATURAS

DIA TMIN TMAX TMED01/05/2007 10 22 1602/05/2007 9 22 1603/05/2007 8 18 1304/05/2007 7 20 14.............. ... ... ...

Page 11: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

11

b) Listar los días en que la temperatura mínima fue mayor que la mínima de las máximas

SELECT * FROM TEMPERATURAS (mostrar registros completos) WHERE TMIN > (SELECT MIN(TMAX) FROM TEMPERATURAS)

c) Se dispone de una tabla de conversión de grados Celsius a Fahrenheit, redondeada a valores enteros (la fórmula de conversión exacta es Fahrenheit = 9 / 5 Celsius + 32 ) GRADOS

CELSIUS FAHRENHEIT... ...0 321 342 36... ...20 68... ...

Listar la temperatura promedio Fahrenheit que hizo cada día. Aquí hay que realizar una equirreunión de tablas.

SELECT DIA, FAHRENHEIT FROM TEMPERATURAS, GRADOS WHERE TMED = CELSIUS

Ejemplo 2

Se dispone de una tabla de alumnos con la siguiente estructura:

TABLA PARCIALES NROLEGAJO C(8) Número de legajo, clave primaria APELLIDO C(20) NOMBRE C(20) NOTA1 C(20) Nota del primer parcial NULL NOTA2 C(20) Nota del segundo parcial NULL CONDICION C(1) NULL

Se suponen cargadas las notas de los alumnos que rindieron parciales, pero no la condición.

a) Calcular la cantidad de alumnos del curso

SELECT COUNT(*) FROM PARCIALES

b) Eliminar los alumnos que no se presentaron a ningún parcial

DELETE FROM PARCIALES WHERE NOTA1 IS NULL AND NOTA2 IS NULL

c) Para cada parcial, listar los alumnos que lo aprobaron (nota >= 6), en orden descendente de nota.

SELECT NROLEGAJO, APELLIDO, NOMBRE, NOTA1 FROM PARCIALES WHERE NOTA1>=6 ORDER BY NOTA1, APELLIDO, NOMBRE (ídem NOTA2) (A igualdad de nota, el listado es alfabético)

d) Colocar una “P” (promovido) en el campo CONDICION para aquellos alumnos que aprobaron ambos parciales, y una “L” (libre) para aquellos que no aprobaron o no asistieron a ninguno de los dos

Page 12: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

12

UPDATE PARCIALES SET CONDICION = ‘P’ WHERE NOTA1 >=6 AND NOTA2 >=6

UPDATE PARCIALES SET CONDICION = ‘L’ WHERE (NOTA1<6 OR NOTA1 IS NULL) AND (NOTA2<6 OR NOTA2 IS NULL)

e) A partir de la tabla PARCIALES, crear otra tabla

NOTASLEGAJO PARCIAL

TMINNOTA

A-2621/8 1 9 A-2621/8 2 8.............. ... ...

donde las notas de los dos parciales aparecen en la misma columna, y el campo PARCIAL identifica de qué parcial se trata. Incluir sólo los parciales que tienen nota. Establecer como clave primaria la combinación LEGAJO, PARCIAL.La solución se obtiene mediante una operación de unión.

SELECT NROLEGAJO AS LEGAJO, 1 AS PARCIAL, NOTA1 AS NOTA INTO NOTAS FROM PARCIALES WHERE NOTA1 IS NOT NULL UNION SELECT NROLEGAJO, 2, NOTA2 FROM PARCIALES WHERE NOTA2 IS NOT NULL ORDER BY LEGAJO

ALTER TABLE NOTAS ADD PRIMARY KEY (LEGAJO, PARCIAL) (la sintaxis de este comando puede variar)

Puede haber alguna dificultad para ejecutar “INTO NOTAS” desde ACCESS, por haber una operación de unión. En tal caso, eliminar la cláusula “INTO NOTAS”, y guardar el comando con un nombre cualquiera, p. ej. CONSULTA1. Luego hacer

SELECT * INTO NOTAS FROM CONSULTA1

Ejemplo 3

En la base de datos de una industria aparecen las tablas INSUMOS

NRO DESCRIP PRECIO 115 BENCENO 4.25 123 ACETONA

30 3.86

132 BENCENO 4.40..............

............... ...............

COMPRAS FECHA NRO CANTIDAD06/03/2008 123 450017/03/2008 115 6000.............. ...........

...................

a) ¿Hay insumos con la misma descripción y distinto número?Este es un problema clásico de manejo de tablas: comparar datos que están en distintos registros de una misma tabla, y una solución usual, empleando SQL, es hacer la reunión de la tabla consigo misma. Para esto se la debe declarar con dos alias distintos.

Page 13: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

13

SELECT A.NRO, A.DESCRIP, B.NRO, B.DESCRIP FROM INSUMOS A, INSUMOS B WHERE A.DESCRIP = B.DESCRIP A.NRO < B.NRO

Observar que no pedimos A.NRO <> B.NRO sino A.NRO < B.NRO, así evitamos que la misma combinación de insumos aparezca dos veces en distinto orden. En definitiva el resultado es

A.NRO A.DESCRIPR

B.NRO B.DESCRIP 115 BENCENO 123 BENCENO ..... ................. ..... .................

b) Ingresar la descripción de un insumo y mostrar la cantidad total comprada de los insumos que tienen esa descripción.

SELECT SUM(CANTIDAD) FROM INSUMOS A, COMPRAS B WHERE A.NRO = B.NRO AND DESCRIPCION=D

Aquí D representa una variable, la descripción de los insumos que estamos considerando. En FOX no es problema ingresar D, ya sea con @ SAY GET o cualquier recurso visual. En cambio, ACCESS en general no utiliza variables, sin embargo, si ejecutamos una consulta como la de arriba no la rechaza, sino que hace aparecer un cuadro “INPUT BOX” pidiendo ingresar el valor de D. Es lo que en ACCESS se llama “consulta de parámetros”.

c) Considerar que la industria tiene dos plantas, 1 y 2, y que cada una construye su propia tabla de compras con la misma estructura

COMPRAS1 – COMPRAS2

FECHA NRO CANTIDAD

La tabla INSUMOS es común a ambas plantas. Si quisiéramos procesar en conjunto las compras de las dos plantas, nos sentiríamos tentados a hacer la unión de COMPRAS1 con COMPRAS2, pero hay un peligro: registros repetidos que se eliminarían al hacer la unión, y que representan compras que no queremos eliminar. La solución es unir las tablas colocando en cada registro un nuevo campo que identifique a la planta, de manera que los registros no puedan repetirse.

SELECT FECHA, NRO, CANTIDAD, 1 AS PLANTA INTO [¨TABLE] COMPRAS FROM COMPRAS1 UNION SELECT FECHA, NRO, CANTIDAD, 2 FROM COMPRAS2

Observar que no se pone “2 AS PLANTA”, porque el nombre del campo ya fue establecido con el primer factor de la unión. Ahora asignamos clave primaria. ALTER TABLE COMPRAS ADD PRIMARY KEY (FECHA, NRO, PLANTA)

d) Determinar el importe total de los insumos comprados

SELECT SUM(CANTIDAD*PRECIO) FROM COMPRAS, INSUMOS WHERE COMPRAS.NRO = INSUMOS.NRO

(no es obligatorio usar siempre alias).

Ejemplo 4

Se dispone de una tabla de alumnos ingresantes a la Facultad

INGRESOLEGAJO NOMBRE CARRERA

NOTA.......... ....................... ........

Finalizado el primer cuatrimestre, se crea otra tabla con los códigos de las asignaturas que aprobó cada alumno (máximo 4). Los códigos pueden estar en cualquier orden, ser de distintas carreras, y tomar el valor nulo.

Page 14: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

14

APROBADOSNROLEG MAT1 MAT2 MAT3 MAT4

L-1826/1 I-112 I-111 I-114 I-113 C-3051/3 I-113 I-114 G-2629/0 C-111 C-113 C-112............. .......

Veremos al hablar de normalización, que esta tabla está muy mal diseñada, porque hay campos con el mismo dominio que pueden intercambiarse, y también quedan demasiados lugares nulos. Además ¿qué sucede si en vez de 4 materias son 5? Hay que reformar toda la tabla. No obstante, podemos igualmente procesarla con SQL.

a) Listar alfabéticamente los alumnos que aprobaron la materia I-111

SELECT LEGAJO, NOMBRE FROM INGRESO, APROBADOS WHERE LEGAJO = NROLEG AND (MAT1=’I-111’ OR MAT2=’I-111’ OR MAT3=’I-111’ OR MAT4=’I-111’) ORDER BY NOMBRE

Aquí se ve la dificultad de tener que buscar la materia en 4 campos que pueden contenerla indistintamente. ¿Y si fueran 10 campos?

b) Reformar la tabla APROBADOS para que en cada registro contenga un solo alumno y una sola materia, eliminando valores nulos. SELECT NROLEG, MAT1 AS MAT INTO APROB1 FROM APROBADOS WHERE MAT1 IS NOT NULL UNION SELECT NROLEG, MAT2 FROM APROBADOS WHERE MAT2 IS NOT NULL UNION SELECT NROLEG, MAT3 FROM APROBADOS WHERE MAT3 IS NOT NULL UNION SELECT NROLEG, MAT4 FROM APROBADOS WHERE MAT4 IS NOT NULL

ALTER TABLE APROB1 ADD PRIMARY KEY (NROLEG, MAT)

c) En APROB1 sólo aparecen los alumnos que aprobaron alguna materia. ¿Cómo hacer para que también incluya a los que no aprobaron ninguna? SELECT LEGAJO, MAT INTO APROB2 FROM INGRESO LEFT JOIN APROB1 ON LEGAJO=NROLEG En APROB2, cada alumno aparece en tantos registros como materias aprobó, identificadas por el campo MAT. Si el

alumno no aprobó ninguna materia, igualmente aparece en un registro, en el cual el campo MAT toma valor nulo. Esta presencia de campos nulos traería dificultades para asignar una clave primaria a APROB2.

d) Listar las carreras que tienen alumnos cuyo apellido comienza con ‘G’ y no han aprobado ninguna asignatura.

SELECT DISTINCT CARRERA . FROM INGRESO, APROB2 WHERE LEGAJO = NROLEG AND LEGAJO >= ‘G’ AND LEGAJO <’H’ AND MAT IS NULL

¿Qué significa SELECT DISTINCT? Ocurre que CARRERA no es un campo clave, se repite en los distintos registros, y el gestor repetiría su valor cada vez que se satisface la condición (aunque no debería ocurrir en el modelo relacional). La cláusula DISTINCT impone al gestor la obligación de mostrar sólo valores distintos en el resultado.

Page 15: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

15

UNIDAD 5.- OTRAS CARACTERISTICAS DE SQL

Agrupamiento de registros

Consideremos una tabla

FACTURASNROFAC CLIENTE IMPORTE

1001 408 1312.25 1002 426 515.10 1003 408 620.00 ......... ....... ...........

Mediante funciones de agregado podemos, p. ej., sumar los importes de toda la tabla, o los que cumplen determinada condición, p. ej., corresponder a un determinado cliente.

SELECT CLIENTE, SUM (IMPORTE) AS TOTAL FROM FACTURAS WHERE CLIENTE = 408

Pero si quisiéramos hacerlo con todos los clientes, deberíamos ejecutar un comando para cada uno. Para resolver mejor este problema, SQL incorpora la posibilidad se sumar los valores de un campo (o promediar, hallar el máximo, etc.) en grupos en los cuales otro campo o campos toman el mismo valor. P. ej. en la tabla anterior, sumar los valores del campo IMPORTE para cada grupo de registros en los cuales el cliente es el mismo. Se genera así otra tabla, en la cual un campo es el campo de referencia o agrupamiento (en este caso el número de cliente), y otro campo es el campo de totales o agregados correspondientes a ese cliente. La sintaxis para este ejemplo es la siguiente:

SELECT CLIENTE, SUM (IMPORTE) AS TOTAL FROM FACTURAS GROUP BY CLIENTE

CLIENTE TOTAL 408 1932.25 426 515.10

En la tabla resultante pueden eventualmente aparecer otros campos, pero sólo si toman el mismo valor en todo el grupo. P. ej. sería incorrecto

SELECT NROFAC, CLIENTE, SUM (IMPORTE) FROM FACTURAS GROUP BY CLIENTE

porque para un mismo cliente, los números de factura son distintos. ACCESS lo rechaza, pero en alguna versión de FOX que lo admite, lo que aparece en el resultado como NROFAC es el número de la última factura del grupo, lo cual no tiene mucho significado.

La cláusula GROUP BY puede incluir más de un campo, o sea el agrupamiento se hace para cada combinación posible de esos campos. P. ej.

SELECT MAX(IMPORTE) FROM FACT1 GROUP BY FECHA, ARTICULO

(se agrupan los importes facturados de cada artículo en cada fecha).

Page 16: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

16

El procesamiento de los resultados de un GROUP BY puede todavía elaborarse más, seleccionando sólo algunos registros de la tabla resultante mediante una cláusula HAVING

SELECT CLIENTES, SUM(IMPORTE) AS TOTAL FROM FACTURAS WHERE NROFAC > 1300 GROUP BY CLIENTE HAVING TOTAL >= 1000 ORDER BY TOTAL DESC

HAVING es como un WHERE, pero actúa sobre la tabla ya agrupada, por eso se pueden emplear los alias. Con WHERE no pueden intervenir alias. HAVING se coloca después de GROUP BY y antes de ORDER BY.

Ejemplo 5

Una fábrica provee a un cliente piezas cilíndricas, que se identifican por su diámetro y altura en mm. Se crean las tablas PIEZAS, con el detalle de las entregas efectuadas, y PRECIOS, con el precio de cada pieza.

PIEZAS FECHA DIAMETRO ALTURA CANTIDAD

03/03/2008 15 40 30005/03/2008 20 30 50005/03/2008 15 40 50010/03/2008 25 40 40004/04/2008 20

3030 700

.............. ... ... ...

PRECIOS DIAMETRO ALTURA PRECIO 15 40 3.45 20 30 3.00 25 40

ENDOZ40 4.10

.............. ............... ...............

a) Listar la cantidad total entregada de cada pieza SELECT DIAMETRO, ALTURA, SUM (CANTIDAD) AS ENTREGA FROM PIEZAS GROUP BY DIAMETRO, ALTURA

b) Listar la cantidad de piezas entregadas cada mes

SELECT MONTH(FECHA) AS MES, SUM(CANTIDAD) AS ENTREGA FROM PIEZAS GROUP BY MONTH(FECHA)

c) Hacer lo mismo, pero discriminando el tipo de pieza SELECT MONTH(FECHA) AS MES, DIAMETRO, ALTURA, SUM(CANTIDAD) AS ENTREGA FROM PIEZAS GROUP BY MONTH(FECHA), DIAMETRO, ALTURA

d) Listar en orden decreciente los importes facturados de cada pieza SELECT A.DIAMETRO AS DIAMETRO, A.ALTURA AS ALTURA, SUM(CANTIDAD * PRECIO) AS IMPORTE FROM PIEZAS A, PRECIOS B WHERE A.DIAMETRO = B.DIAMETRO AND A.ALTURA = B.ALTURA GROUP BY A.DIAMETRO, A.ALTURA ORDER BY SUM(CANTIDAD * PRECIO) DESC

Page 17: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

17

e) Listar las fechas en que se entregó más de un tipo de pieza

SELECT FECHA, CNT(FECHA) AS TIPOS FROM PIEZAS GROUP BY FECHA HAVING TIPOS > 1

f) Listar los meses en que el importe facturado superó $ 100.000.-

SELECT MONTH(FECHA) AS MES, SUM(CANTIDAD * PRECIO) AS IMPORTE FROM PIEZAS A, PRECIOS B WHERE A.DIAMETRO = B.DIAMETRO AND A.ALTURA = B.ALTURA GROUP BY MES HAVING IMPORTE > 100000 Subconsultas

Una subconsulta es una consulta contenida en otra, de tal manera que debe ejecutarse antes que la consulta que la contiene. Eventualmente, la consulta principal puede proporcionar parámetros a la subconsulta. Puede haber nidos de subconsultas, p. ej. en 2 ó 3 niveles; más niveles pueden complicar el planteo y la ejecución.

Las subconsultas pueden aparecer en comandos SELECT y UPDATE, y van siempre después del WHERE, es decir, sólo pueden emplearse para definir condiciones. No se pueden definir los campos de la selección ni las tablas de donde provienen mediante subconsultas

NO NO SI

SELECT campo1, campo2,... FROM tabla1, tabla2 WHERE condición

Ya habíamos empleado algunas subconsultas sencillas, que devuelven un valor numérico. P. ej.

SELECT * FROM PRECIOS WHERE PRECIO > (SELECT AVG(PRECIO) FROM PRECIOS)

Observar que en este caso, aunque la subconsulta afecta a la misma tabla que la consulta principal, no es necesario emplear alias. Veremos cuándo es necesario en otros casos.

Cláusulas IN, NOT IN

Muchas veces, el resultado de una subconsulta depende de si el valor de determinado campo o expresión está o no en una lista de valores. La lista puede ser un conjunto de constantes (o variables, si el gestor las admite) separadas por comas, pero es más usual que la lista se forme con los valores de un campo o expresión proveniente otra tabla. La condición se expresa mediante los operadores IN y NOT IN, que devuelven un valor lógico, verdadero o falso según si la expresión pedida se encuentre o no. NOT IN devuelve el opuesto de IN. P. ej.

SELECT * FROM EMPLEADOS WHERE NROEMPLE IN (1, 4, 5)

muestra los datos de los empleados cuyo número es 1, 4 ó 5.

SELECT * FROM EMPLEADOS WHERE NROEMPLE NOT IN (SELECT NROEMPLE FROM PEDIDOS WHERE FECHA=DATE())

muestra los datos de los empleados que hoy no han atendido ningún pedido.

Ejemplo 6

Page 18: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

18

Una empresa de transportes registra sus vehículos en la tabla

CAMIONESINTERNO PATENTE MARCA

401 ABC123 SCANIA402 ATG444 FIAT403 CAB531 MERCEDES..... ............. .....................

y los viajes efectuados, en la tabla

VIAJESNVIAJE FECHA NROINT KM

1001 01/07/2009 401 2151002 01/07/2009 403 1461003 02/07/2009 403 1201004 02/07/2009 402 320....... ............... ...... ......

a) Listar las patentes de los vehículos que viajaron el 1/7/2009 Una forma de hacerlo es mediante reunión de tablas

SELECT DISTINCT PATENTE FROM CAMIONES, VIAJES WHERE INTERNO = NROINT AND FECHA = {1/7/2009} donde el comando SELECT DISTINCT evita que las patentes aparezcan repetidas. Ya aclaramos más arriba que no siempre el gestor verifica si hay tuplas repetidas en el resultado. Otra forma es emplear una subconsulta

SELECT PATENTE FROM CAMIONES WHERE INTERNO IN (SELECT NROINT FROM VIAJES WHERE FECHA = {1/7/2009})

b) Listar los vehículos que no viajaron el 1/7/2009

En este caso, una reunión de tablas no solucionaría el problema. En cambio, con una subconsulta, el resultado es inmediato SELECT PATENTE FROM CAMIONES WHERE INTERNO NOT IN (SELECT NROINT FROM VIAJES WHERE FECHA = {1/7/2009})

c) Listar los kilómetros recorridos por cada camión en el mes de julio de 2009. Incluir los camiones que no viajaron en todo el mes, asignándoles kilometraje 0

Si las operaciones se efectúan sólo en la tabla VIAJES, no aparecen los camiones que no viajaron. Estos hay que buscarlos en la tabla CAMIONES, y hacer la unión de resultados.

SELECT INTERNO, PATENTE, SUM(KM) AS DISTANCIA FROM CAMIONES, VIAJES WHERE INTERNO = NROINT AND FECHA BETWEEN {1/7/2009} AND {31/7/2009} GROUP BY INTERNO UNION SELECT INTERNO, PATENTE, 0 FROM CAMIONES

WHERE INTERNO NOT IN (SELECT NROINT FROM VIAJES WHERE FECHA BETWEEN {1/7/2009} AND {31/7/2009})

Page 19: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

19

También se podría resolver el problema mediante una reunión externa izquierda, aunque en este caso los camiones que no viajaron aparecerían con kilometraje null.

SELECT INTERNO, PATENTE, SUM(KM) AS DISTANCIA FROM CAMIONES LEFT JOIN VIAJES ON INTERNO = NROINT AND FECHA BETWEEN {1/7/2009} AND {31/7/2009} GROUP BY INTERNO

Cláusulas EXISTS, NOT EXISTS

Tienen una aplicación similar a IN, NOT IN, pero lo que se comprueba ahora es la existencia de algún registro en una subconsulta (EXISTS verdadero), o bien que el resultado de la subconsulta es vacío (EXISTS falso o NOT EXISTS verdadero). P. ej. para mostrar los empleados que hoy no atendieron pedidos, en vez de una consulta con NOT IN podemos hacer:

SELECT * FROM EMPLEADOS A WHERE NOT EXISTS (SELECT * FROM PEDIDOS WHERE NROEMPLE =A.NROEMPLE AND FECHA=DATE())

Observar que la consulta exterior pasa un parámetro (NROEMPLE) a la subconsulta, y dentro de la subconsulta ese parámetro debe compararse con un campo de la tabla PEDIDOS. Como los nombres de campo coinciden, es necesario utilizar un alias A para referirse a la tabla exterior.

Ejemplo 7

En la base de datos del ejemplo 6, listar los camiones que viajaron todos los días.

Para resolver este problema se necesitan subconsultas anidadas, y las analizaremos en cada nivel. Sea INTERNO el número de un camión determinado (pensarlo como parámetro). Si el camión viajó todos los días, la consulta

SELECT FECHA FROM VIAJES WHERE NROINT = INTERNO

dará como resultado todas las fechas de la tabla VIAJES; pero si algún día el camión no viajó, faltará esa fecha. Las fechas que faltan pueden identificarse en una consulta NOT IN que incluya la anterior

SELECT FECHA FROM VIAJES WHERE FECHA NOT IN (SELECT FECHA FROM VIAJES WHERE NROINT = INTERNO)

Ahora bien, si el camión viajó todos los días, el resultado de esta última consulta es vacío, NOT EXISTS es verdadero. Entonces éste es el criterio a adoptar en la consulta principal.:

SELECT INTERNO, PATENTE FROM CAMIONES WHERE NOT EXISTS ( SELECT FECHA FROM VIAJES WHERE FECHA NOT IN (SELECT FECHA FROM VIAJES WHERE NROINT = INTERNO))

Recurso complementario: Comando SELECT TOP

Cuando en una consulta SELECT, el resultado aparece ordenado mediante una cláusula ORDER BY, se puede pedir la visualización, o sea la selección de sólo los n primeros registros de ese resultado ordenado. La cantidad n en general es constante, aunque en FOX puede ser variable, y la forma del comando es

Page 20: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

20

SELECT TOP n campo1, campo2, ... FROM tabla1, tabla2, ...... WHERE condición ORDER BY expresiónP. ej. SELECT TOP 3 * FROM CAMIONES ORDER BY MARCA

Este recurso no sólo es importante para visualizar resultados, sino para realizar operaciones y construir subconsultas limitadas a determinados registros. Ejemplos adicionales de resolución

Ejemplo 8Una línea aérea dispone de una tabla de vuelos con origen y destino

VUELOS NVUELO ORIGEN DESTINO 101 ROSARIO MENDOZA 102 CORDOBA

9ROSARIO

103 MENDOZA TUCUMAN 104 TUCUMAN MENDOZA 105 ROSARIO CORDOBA.............. ............... ...............

a) Identificar los vuelos donde el origen y el destino aparecen intercambiados (P. ej. 103 con 104, 102 con 105) Se tratade comparar información existente en distintos registros de una misma tabla, y un buen criterio para resolver este tipo de problemas en SQL es efectuar la reunión de la tabla consigo misma

SELECT A.NVUELO, A.ORIGEN, A.DESTINO B.NVUELO, B.ORIGEN, B.DESTINO FROM VUELOS A, VUELOS B WHERE A.ORIGEN = B.DESTINO AND B.ORIGEN = A.DESTINO AND A.NVUELO < B.NVUELO

A.NVUELO A.ORIGEN A.DESTINO B.NVUELO B.ORIGEN B.DESTINO103 MENDOZA TUCUMAN 104 TUCUMAN MENDOZA102 CORDOBA ROSARIO 105 ROSARIO CORDOBA

De no haberse colocado la última condición A.NVUELO < B.NVUELO, los vuelos habrían aparecido repetidos.

A.NVUELO A.ORIGEN A.DESTINO B.NVUELO B.ORIGEN B.DESTINO105 ROSARIO CORDOBA 102 CORDOBA ROSARIO104 TUCUMAN MENDOZA 103 MENDOZA TUCUMAN103 MENDOZA TUCUMAN 104 TUCUMAN MENDOZA102 CORDOBA ROSARIO 105 ROSARIO CORDOBA

b) Dar dos ciudades, y buscar qué combinación de vuelos puede unirlas b1) En una sola etapa

SELECT * FROM VUELOS WHERE ORIGEN = CIUDAD1 AND DESTINO = CIUDAD2

Observar que CIUDAD1 y CIUDAD2 son variables o parámetros que deben ingresarse antes, o durante la ejecución del comando, dependiendo del gestor utilizado.

b2) En dos etapas También aquí conviene hacer la reunión de la tabla consigo misma

Page 21: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

21

SELECT * FROM VUELOS A, VUELOS B WHERE A.ORIGEN = CIUDAD1 AND B.DESTINO = CIUDAD2 AND A.DESTINO = B.ORIGEN

c) El movimiento se registra en la tabla PASAJEROS, y la empresa posee 20 aviones, numerados de 1 a 20

PASAJEROS NBOLETO FECHA DNI VUELO AVION

Calcular cuántos pasajeros (boletos) llegaron a Córdoba en el otoño de 2009

SELECT CNT(NBOLETO) FROM PASAJEROS, VUELOS WHERE VUELO = NVUELO AND DESTINO = ‘CORDOBA’ AND FECHA BETWEEN {21/3/2009} AND {20/6/2009} (o #21/03/2009# AND #20/06/2009#) d) Listar los pasajeros que realizaron más de un viaje

El problema se puede resolver de dos maneras- mediante reunión de la tabla PASAJEROS consigo misma

SELECT DISTINCT A.DNI FROM PASAJEROS A, PASAJEROS B WHERE A.DNI = B.DNI AND A.NBOLETO <> B.NBOLETO

- mediante agrupamiento de registros SELECT DNI, CNT(NBOLETO) AS VIAJES FROM PASAJEROS GROUP BY DNI HAVING VIAJES > 1 ORDER BY VIAJES DESC

e) ¿En qué vuelos no se empleó nunca el avión número 20?

SELECT VUELO FROM VUELOS WHERE VUELO NOT IN (SELECT VUELO FROM PASAJEROS WHERE AVION = 20)

f) ¿Qué avión transportó la mayor cantidad de pasajeros?

SELECT TOP 1 AVION, COUNT(*) AS PASAJE FROM PASAJEROS GROUP BY AVION ORDER BY PASAJE DESC Ejemplo 9: Cálculo de totales acumulados.

Consideremos una tabla de ventas diarias DIARIO

FECHA INGRESO 01/07/2007 610.12 02/07/2007 405.20 03/07/2007 538.44 ...... ......

Podría interesarnos calcular día a día los ingresos acumulados desde la fecha inicial. Si bien el problema es sencillo de resolver mediante programación, vamos a intentar resolverlo empleando sólo SQL. Vemos que, para hacer la suma, en cada registro hay que incorporar valores que provienen de otros registros, en este caso los anteriores en orden de fecha. Entonces, como primera medida, hacemos la reunión de la tabla consigo misma, con la condición de que las fechas de la derecha sean menores o iguales que las de la izquierda.

Page 22: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

22

TABLA1 A.FECHA A.INGRESO B.FECHA B.INGRESO

01/07/2009 610.12 01/07/2009 610.1202/07/2009 405.20 01/07/2009 610.1202/07/2009 405.20 02/07/2009 405.2003/07/2009 538.44 01/07/2009 610.1203/07/2009 538.44 02/07/2009 405.2003/07/2009 538.44 03/07/2009 538.44

Ahora sumamos el campo B.INGRESO de TABLA1, agrupándolo por A.FECHA

SELECT A.FECHA, A.INGRESO, SUM(B.INGRESO) FROM TABLA1 GROUP BY A.FECHA

Es correcto incorporar el campo A.INGRESO a la selección, porque sus valores se repiten en cada grupo. De todos modos, si hubiera alguna dificultad, hacer

SELECT A.FECHA, MAX(A.INGRESO), SUM(B.INGRESO) ..............ya que, en definitiva, el resultado va a ser el mismo. En realidad, no es necesario construir explícitamente TABLA1, pues la solución puede obtenerse con el único comando

SELECT A.FECHA AS FECHA, A.INGRESO AS INGRESO SUM(B.INGRESO) AS TOTAL FROM DIARIO A, DIARIO B WHERE B.FECHA <= A.FECHA GROUP BY A.FECHA

el cual produce FECHA INGRESO TOTAL

01/07/2009 610.12 610.1202/07/2009 405.20 1015.3203/07/2009 538.44 1553.76

..... ..... .....

Ejemplo 10: El problema del ballottage.En la elección para presidente de una institución se presentan varios candidatos, y se registran en una tabla los porcentajesde votos que obtuvo cada uno. El reglamento establece que será ganador el candidato con mayor porcentaje, si éste supera el 40%. De no ser así, habrá un ballottage entre los dos candidatos más votados. Mediante un único comando SQL mostrar el resultado de la elección. ELECCION

NOMBRE PORCENTAcosta 19Borgonovo 33Fino 38Martínez 7Otros 3

Dentro de la consulta se arma una tabla intermedia, ordenada por porcentaje decreciente de votos, que puede tener un solo registro, el del candidato que obtuvo el máximo porcentaje, si supera el 40%, o bien todos los registros, si ninguno excede ese porcentaje. A esa tabla se le aplica un SELECT TOP 2. En caso de haber un solo registro, sólo mostrará ese registro.

SELECT TOP 2 * FROM ELECCION WHERE PORCENT > 40 AND PORCENT = (SELECT MAX(PORCENT) FROM ELECCION) OR NOT EXISTS (SELECT * FROM ELECCION WHERE PORCENT > 40) ORDER BY PORCENT DESC

Page 23: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

23

UNIDAD 6.- NORMALIZACION DE BASES DE DATOS

La normalización es una técnica para el diseño de bases de datos, en la que, dentro del modelo relacional, se sugieren criterios o formas normales a las cuales deben ajustarse las relaciones o tablas, de manera de evitar la repetición o redundancia de la información, eliminar dependencias inconsistentes, y facilitar el agregado o supresión de datos sin tener que modificar las estructuras. Se definen usualmente cinco formas normales: 1, 2 , 3, 4, 5. Cada una incluye a la anterior y agrega nuevas exigencias. Existe además la forma normal de Boyce-Codd, que se puede considerar como un complemento de la tercera forma normal. Las formas 4 y 5 son menos frecuentes, y se refieren a exigencias muy particulares.La normalización de una base de datos es aconsejable pero no obligatoria. Los gestores y lenguajes trabajan igualmente con bases no normalizadas, pero la normalización mejora la eficiencia. Podría darse el caso de que, al pretender normalizar hasta el último detalle bases de datos pequeñas, haya que crear tablas adicionales que sólo supriman la posible ocurrencia de un par de redundancias y compliquen el trabajo. Por lo tanto, al diseñar una base de datos, hay que buscar soluciones de compromiso, viendo hasta qué nivel conviene normalizar. Primera forma normal

Consideremos la siguiente tabla de despacho de mercadería (en esta y otras tablas subrayamos la clave primaria):

DESPACHO

NREMITO NCLI NOMCLI NA1 NOM1 PART1 C1 NA2 NOM2 PART2 C2 NA3 NOM3 PART3 C3

1561 215 ARROYO 16 TORNILLO 16-507 5000 17 TUERCA 17-530 3000 21 BULON 21-509 1000

1562 228 GARCIA 17 TUERCA 17-530 2000 26 REMACHE 26-529 2000

1563 215 ARROYO 21 BULON 21-512 3000

.... .......... ..

........ ......... ...... .. ............ ..........

NREMITO: número de remitoNCLI: número de clienteNOMCLI: nombre del clienteNA1, NA2, NA3: números de artículoNOM1, NOM2, NOM3: nombres de artículoPART1, PART2, PART3: partidas de fabricaciónC1, C2, C3: cantidades entregadas de cada artículo

Suponemos que en cada remito no se despachan más de 3 artículos, y que no puede haber, en el mismo remito, el mismo artículo de partidas diferentes. El diseño de esta tabla presenta algunos problemas:1) En cada registro, un mismo dato, p. ej. un número de artículo, puede colocarse indistintamente en cualquiera de tres

campos NA1, NA2 y NA3, si que se altere la función que cumple. Campos como NA1, NOM1, etc. no tienen significado por sí mismos, y pueden llenarse o no llenarse. Tablas como ésta suelen traer dificultades de procesamiento

2) ¿Por qué la cantidad máxima de artículos tiene que ser 3? ¿Qué pasaría si en algún momento necesitamos despachar 10? Habría que alterar la estructura de la tabla y agregar nuevos campos, que después la mayor parte de las veces quedarán en nulo.

3) Ya sabemos que las operaciones en horizontal son menos ágiles que en vertical, y necesitan recursos de programación tales como p. ej. los vectores.

Decimos que la tabla DESPACHO no está en primera forma normal (1FN). Otro ejemplo de tabla que no está en 1FN fue mencionado en el curso: una tabla en que se colocan indistintamente en cuatro campos los códigos de las asignaturas que aprobó cada alumno en el primer cuatrimestre. APROBADOS

LEGAJO MAT1 MAT2 MAT3 MAT4L-1826/1 I-112 I-111 I-114 I-113C-3051/3 I-113 I-114............. .......

En cambio, en los ejercicios de la práctica aparece una tabla de 40 columnas, donde cada una contiene la nota de una materia específica (p. ej. la primera Algebra, la segunda Informática, etc.), y entonces no es indistinto colocar un dato encualquier columna. Los inconvenientes de esa tabla son que en cada registro hay demasiados campos juntos de un mismo dominio, es decir excesiva necesidad de procesamiento horizontal, por lo que podría buscarse darle una forma mejor, colocando cada asignatura en un registro separado. Vamos a dar entonces la definición de primera forma normal.

Page 24: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

24

Definición: Decimos que una tabla está en la primera forma normal (1FN) cuando en cada registro, un dato que cumple una función específica sólo puede almacenarse en una campo determinado, y no en varios indistintamente. Otra forma de expresar el concepto: Una tabla es una estructura de datos esencialmente bidimensional (filas y columnas). No hay que agregarle una tercera dimensión, que es lo que ocurriría al hacer que algunos campos se repitan sin tener un significado propio específico. Otra forma: un campo sólo puede contener valores atómicos, o sea indivisibles, que no se comparten con otros campos.

Para llevar la tabla DESPACHO a 1FN, tendríamos que descomponer cada registro en registros separados que contengan cada uno un solo artículo, eliminando los nulos. Nos quedaría lo siguiente:

DESPACHO1

NREMITO NCLI NOMCLI NART NOMART PARTIDA CANT1561 215 ARROYO 16 TORNILLO 16-507 50001561 215 ARROYO 17 TUERCA 17-530 30001561 215 ARROYO 21 BULON 21-509 10001562 228 GARCIA 17 TUERCA 17-530 20001562 228 GARCIA 26 REMACHE 26-529 20001563 215 ARROYO 21 BULON 21-512 3000...... ...... ............... ... ............ ........... .......

En esta tabla, que está mejor organizada que la anterior, cada dato se coloca en un único campo, y no quedan valores nulos. La clave primaria ya no es el número de remito, que se repite, sino la combinación número de remito-número de artículo. Desaparece la restricción de que la cantidad de artículos sea a lo máximo 3, pues ya no hay límite. De todos modos, aparecen ahora redundancias en vertical (p. ej. los nombres de clientes), pero antes de seguir normalizando, vamos a definir un concepto importante.

Dependencia funcional

Dada una relación o tabla, decimos que el atributo Y es funcionalmente dependiente del atributo X, o depende funcionalmente del atributo X, o que X determina funcionalmente a Y, y lo indicamos

X → Y ,

si en cualquier par de tuplas en las que el atributo X toma el mismo valor, tiene también el mismo valor el atributo Y. P. ej. en la tabla DESPACHO1, es evidente que el atributo NOMCLI es funcionalmente dependiente de NCLI. El número de cliente determina al nombre. Cada vez que en un registro se da el número de un cliente, sólo hay una posibilidad en el campo nombre. La recíproca podría no ser cierta: p. ej. dos clientes distintos (distinto número), con igual nombre. Es decir

X → Y no implica Y → X

De todos modos, para caracterizar correctamente una dependencia funcional, hay que tener en cuenta la lógica con que fue diseñada la tabla, o sea el esquema de relación con todas sus restricciones, más que los datos en sí, que pueden ser pocos o no haber ninguno. P. ej. , supongamos que en los datos visibles de la tabla DESPACHO1 se suprimen el primero y tercer registro. Entonces en cada artículo que compra el cliente 215 la cantidad es 3000, y en cada uno que compra el cliente 228 la cantidad es 2000. Esto podría llevar a inferir una dependencia funcional errónea entre los campos NCLI y CANT.

Puede haber dependencia funcional respecto de una combinación de atributos,

X, Y → Z

Con respecto a la primera forma normal, se dice que en ella la clave primaria determina funcionalmente a los otros atributos. Esto es una generalización de la definición, porque la clave primaria no se repite, pero en una tabla no normalizada, la clave primaria no dice en cuál de varios campos debe colocarse cada dato. Además, si se hace una reunión de la tabla dada con otra, de manera que algunos registros de la primera se repitan, todo lo que aparece junto a la clave primaria se repite también.

Segunda forma normal

La segunda forma normal tiene que ver con tablas con clave primaria compuesta, y se trata de eliminar aquellos atributos que dependen funcionalmente de parte de la clave, mandándolos a otras tablas en las que la parte de la clave considerada sea ahora clave primaria.

Page 25: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

25

En la tabla DESPACHO1 buscamos si hay atributos que dependan sólo de la primera parte de la clave, NREMITO. Vemos que ellos son NCLI y NOMCLI, y por tanto creamos una tabla aparte

REMITOS

NREMITO NCLI NOMCLI 1561 215 ARROYO 1562 228 GARCIA 1563 215 ARROYO ........ ... ...........

donde NREMITO es clave primaria, y está en 1FN.Ahora buscamos los campos que dependen funcionalmente de la segunda parte de la clave, NART. Vemos que es sólo NOMART, y procediendo como antes, creamos la tabla.

ARTICULOS

NART NOMART 16 TORNILLO

610.12 17 TUERCA 21 BULON 26 REMACHE ...... ......

en la cual NART es clave primaria, y está en 1FN. La tabla DESPACHO1, entonces, se reduce a

DESPACHO2

NREMITO NART PARTIDA CANT

1561 16 16-507 5000 1561 17 17-530 3000 1561 21 21-509 1000 1562 17 17-530 2000 1562 26 26-529 2000 1563 21 21-512 3000 ...... ... ......... ......

Donde ahora los campos NCLI, NOMCLI y NOMART están en otras tablas, y se vinculan mediante claves externas.

Definición: Decimos que una tabla está en segunda forma normal (2FN) cuando está en 1FN, y además no existe ningún atributo no clave que dependa funcionalmente de parte de la clave primaria.

Observación 1: Si una tabla en 1FN tiene clave primaria simple, ya está en 2FN.

Observación 2: Las tablas DESPACHO2, REMITOS y ARTICULOS están todas en 2FN, luego podemos decir que la base de datos está en 2FN.

Tercera forma normal

Observemos la tabla REMITOS, que está en 2FN. Vemos que, sin embargo, hay un atributo no clave, NOMCLI, que depende funcionalmente de otro atributo no clave, NCLI. Entonces creamos una nueva tabla

CLIENTES

NCLI NOMCLI 215 ARROYO 228 GARCIA ...... ......

Page 26: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

26

de manera que la tabla REMITOS pasa a ser ahora

REMITOS1

NREMITO NCLI 1561 215 1562 228 1563 215 ...... ......

Definición: Decimos que una tabla está en tercera forma normal (3FN) cuando está en 2FN, y no hay atributos no clave que dependan funcionalmente de otros atributos no clave. La tercera forma normal es una de las más usuales, y puede considerarse como una forma standard para la normalización de bases de datos. Ningún atributo no clave puede depender funcionalmente de parte de la clave, ni de otro atributo no clave.

Resumiendo, a partir de la tabla original DESPACHO hemos tenido que crear las tablas

DESPACHO2 (está en 3FN) ARTICULOS REMITOS1 CLIENTES

para tener una base de datos en tercera forma normal. Esto facilita la carga de nuevos datos, p. ej. agregado de nuevos clientes o modificación de nombres de artículos, etc., además de hacer más eficientes las tareas de procesamiento.

Observación 3: Para definir más correctamente las formas normales, más que de atributos clave o no clave, deberíamos hablar de atributos primos o no primos. Se dice que un atributo es primo, cuando forma parte de la clave primaria, o de alguna otra clave candidata. No primo es cuando esto no sucede. Pensemos que a la tabla CLIENTES le agregamos otro atributo CUIT.

CLIENTES1

NCLI NOMCLI CUIT 215 1561

ARROYO 30-16786334-1 228 1562

GARCIA 27-20993626-8 ........

... ...........

El CUIT es único para cada cliente, luego, aunque no esté en la clave principal es una clave candidata, y por tanto es un atributo primo. Ahora bien, en CLIENTES1, el campo no clave NOMCLI depende funcionalmente de CUIT, que tampoco es clave, y de acuerdo a la definición que dimos la tabla no estaría en 3FN y habría que separarla. En realidad, esto no es necesario, si ajustamos la definición de la siguiente manera: Se dice que una tabla está en 3FN cuando está en 2FN y no hay atributos no primos que dependan funcionalmente de otros atributos no primos.

Forma normal de Boyce-Codd

Examinemos la tabla DESPACHO2, que sabemos que está en tercera forma normal. Sin embargo, nos llama la atención que aparezcan valores repetidos en el campo PARTIDA. Analizando mejor, vemos que el campo PARTIDA, que no es clave, determina funcionalmente al campo NART, que es parte de la clave primaria. Pensando en el diseño, cada artículo puede provenir de diversas partidas de fabricación, pero cada partida hace referencia a un solo artículo. En suma, queda todavía una redundancia, pero para modificarla debemos cambiar la clave. Si en DESPACHO2, la combinación NREMITO - NART es única, por ser clave primaria, también lo es la combinación NREMITO - PARTIDA, ya que si se repitiera, también se repetiría el artículo determinado funcionalmente por la partida. Entonces, para eliminar la redundancia, debemos primero cambiar la clave primaria a NREMITO - PARTIDA. Al hacer esto, ya no estamos ni siquiera en 2FN, porque hay un atributo que depende funcionalmente de parte de la clave, y entonces tenemos que crear una nueva tabla

Page 27: INFORMATICA II (Ing. Industrial) – SEGUNDO …15dejuniomnr.com.ar/blog/apunteca/Ciclo Basico/Informatica II... · ... y en tal sentido se lo considera un lenguaje universal para

27

PARTIDAS

PARTIDA NART 16-507 16 17-530 17 21-509 21 21-512 21 26-529 26 ...... ....

de manera que los despachos quedan DESPACHO3

NREMITO PARTIDA CANT

1561 16-507 5000 1561 17-530 3000 1561 21-509 1000 1562 17-530 2000 1562 26-529 2000 1563 21-512 3000 ....... .......... ........

Definición: Decimos que una tabla está en la forma normal de Boyce-Codd (BC) cuando está en 3FN y ningún atributo que forma parte de la clave primaria depende funcionalmente de otro atributo no clave.

Otras formas normales

Se puede seguir perfeccionando la forma de una base de datos, eliminando redundancias debidas a dependencias multivaluadas. Veamos qué es esto. Si Y depende funcionalmente de X,

X → Y ,

Significa que si X toma el valor Xo , Y toma el valor Yo , y nada más que ése.

Xo → Yo ,

Pero podría ocurrir este otro tipo de dependencia:

X → multiv Y ,

Si X toma el valor Xo , Y puede tomar p. ej. los valores Yo , Y 1, Y2 pero no Y 3, Y4 , etc.

es decir, más que un valor único, se determina un rango de valores. La corrección de redundancias debidas a dependencias multivaluadas (4 y 5FN), obliga a construir nuevas tablas, lo que en alguna medida complica el diseño. Este tipo de análisis sólo se justifica en grandes bases de datos, donde hay que considerar y optimizar todas las alternativas posibles.