bases de datos 1 - rua.ua.es¡ctica.pdf · para realizar consultas sobre una base de datos vamos a...

114
práctica Bases de Datos 1 Eva Gómez Ballester Paloma Moreda Pozo Patricio Martínez Barco José Clavel Cerro Ernesto Pérez López Armando Suárez Cueto Dpto. de Lenguajes y Sistemas Informáticos Escuela Politécnica Superior Universidad de Alicante http://www.dlsi.ua.es/asignaturas/bd1/bd1.html

Upload: duongliem

Post on 18-Oct-2018

216 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

práctica

Bases de Datos 1

Eva Gómez Ballester

Paloma Moreda Pozo

Patricio Martínez Barco

José Clavel Cerro

Ernesto Pérez López

Armando Suárez Cueto

Dpto. de Lenguajes y Sistemas Informáticos

Escuela Politécnica Superior

Universidad de Alicante http://www.dlsi.ua.es/asignaturas/bd1/bd1.html

Page 2: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior
Page 3: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

índice

sesión 0_______________________________________________ 5

select 1 _______________________________________________ 9

BD Proveedores _______________________________________ 13

select 2 ______________________________________________ 21

select 3 ______________________________________________ 27

select fecha___________________________________________ 31

create _______________________________________________ 33

manipulación 1 ________________________________________ 41

manipulación 2 ________________________________________ 47

manipulación 3 ________________________________________ 53

conjuntos ____________________________________________ 59

funciones_____________________________________________ 63

group by _____________________________________________ 67

group by - having ______________________________________ 71

subselect_____________________________________________ 75

subselect - exists ______________________________________ 81

adicionales 1 __________________________________________ 83

adicionales 2 __________________________________________ 85

adicionales 3 __________________________________________ 87

adicionales 4 __________________________________________ 89

adicionales 5 __________________________________________ 91

adicionales 6 __________________________________________ 93

adicionales 7 __________________________________________ 95

Page 4: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior
Page 5: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

5

sesión 0

ENTORNO ORACLE Objetivos:

• Adquirir la destreza mínima para trabajar en el entorno ORACLE iSQLplus.

Contenidos

• Concepto de Base de Datos y Tabla. • Entrar en ORACLE SQL. • Manejo de menús. • Selección de Base de Datos. • Tipos de datos. • Ayuda en línea. • Salvar y recuperar órdenes SQL.

Concepto de Base de Datos y Relación (Tabla) Una base de datos es un conjunto de información interrelacionada que representa un sistema

de información particular, y está compuesta por relaciones, o más comúnmente tablas, que almacenan los datos referentes a un objeto o a una interrelación entre objetos.

Así, si queremos mantener mediante un gestor de bases de datos información docente, lo que haremos (en este caso en particular) será crear una base de datos que englobe tres tablas: PROFESORES, ASIGNATURAS e IMPARTE. Cada tabla tendrá sus columnas, que representan los correspondientes atributos de la entidad o claves ajenas que permiten relacionar varias tablas entre sí. La BD que gestione esta información se llamará Ejemplo, y las tablas contenidas en ella se presentan en el siguiente cuadro.

Base de Datos: Ejemplo

PROFESORES ( dni : varchar(10), nombre : varchar(40), categoria : char(4), ingreso : date ) Clave primaria: dni

ASIGNATURAS ( codigo : char(5), descripcion : varchar(35), creditos : number(3,1), creditosp : number(3,1) )

Clave primaria: codigo

IMPARTE ( dni : varchar2(10), asignatura : char(5) ) Clave primaria: (dni, asignatura) Clave ajena: dni → PROFESORES Clave ajena: asignatura → ASIGNATURAS

Page 6: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

6

Extensiones de Ejemplo:

ASIGNATURAS

codigo descripcion creditos creditospHI HISTORIA DE LA INFORMATICA 4.5 FBD FUNDAMENTOS DE LAS BASES DE DATOS 6.0 1.5 DGBD DISEÑO Y GESTION DE BASES DE DATOS 6.0 3.0 PC PROGRAMACION CONCURRENTE 6.0 1.5 FP FUNDAMENTOS DE LA PROGRAMACION 9.0 4.5

PROFESORES IMPARTE

dni nombre categoria ingreso dni asignatura 21111222 EVA GOMEZ TEU 01/10/1993 21111222 FBD 21222333 MANUEL PALOMAR TEU 16/06/1989 21111222 DGBD 21333444 RAFAEL ROMERO ASO6 16/06/1992 21333444 PC

iSQLplus

Oracle es un sistema de gestión de bases de datos relacional. Dicho gestor está instalado en un servidor al que se accede por red desde un navegador o un cliente Windows.

Desde el navegador, accediendo a la dirección http://oraculo.eps.ua.es:5560/isqlplus, aparece la pantalla de identificación. Para la mayoría de las sesiones, la información a introducir en el formulario es:

Usuario: alumno

Contraseña: alumno

Conexión: oracle

Una vez el sistema permite la conexión, disponemos de un área donde introducir órdenes SQL cuyo resultado se obtiene pulsando el botón “Ejecutar”. Podemos probar con la siguiente consulta:

select * from profesores

resultado: dni nombre categoria 21111222 EVA GOMEZ TEU 21222333 MANUEL PALOMAR TEU 21333444 RAFAEL ROMERO ASO6

Tipos de datos

En general, la utilización de varias tablas necesita que ellas se puedan relacionar por una columna común, en este caso dni de profesor, para la relación entre imparte y profesor, y codigo de asignatura, para la relación entre asignatura e imparte. Nótese, sin embargo, que en la tabla imparte el código de asignatura se llama asignatura y en la tabla asignaturas codigo. En realidad, tales atributos son “comunes” porque el dominio es el mismo para ambos y se pueden comparar. Los dominios vienen definidos por los tipos de datos que ofrece el SGBD.

Los tipos de datos que acompañan en el esquema de BD a cada columna en cada tabla determinan los valores que pueden tomar éstas. Son de capital importancia a la hora de relacionar tablas en una sentencia select, puesto que sólo podremos comparar columnas con idéntico tipo de datos, o a la hora de manipular datos, dado que, como veremos en próximas sesiones, cada tipo de datos presenta unos requisitos específicos para su manipulación.

Page 7: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

7

Algunos de los tipos de datos que nos podemos encontrar en ORACLE son:

VARCHAR2(n) Cadena de caracteres de longitud variable con un máximo de n (1<=n<=4000)

CHAR(n) Cadena de caracteres de longitud fija de longitud n (1<=n<=2000) LONG Cadena de caracteres de longitud variable hasta 2 gigabytes, o 231-1 bytes

NUMBER(p,s) Números con precisión p y escala s (1<=p<=38) (-84<=s<=127) RAW(n) Cadena de caracteres binarios de longitud n (1<=n<=2000)

LONG RAW Cadena de caracteres binarios de longitud variable hasta 2 gigabytes DATE Datos de tipo fecha, con la forma dd/mm/yyyy(día, mes y año). Los valores

date deben manejarse encerrados entre comillas simples. Rango válido desde 1 de enero de 4712 AC hasta el 31 de diciembre de 4712 DC.

INFORMACIÓN ADICIONAL

Ayuda en línea.

Direcciones con ayuda Oracle disponible:

• www.oracle.com

• www.redcientifica.com/ En general, es bastante fácil encontrar información en internet por medio de cualquier

buscador.

Obtener información sobre una tabla de la BD

Ejecutar DESC nombreTabla o DESCRIBE nombreTabla para mostrar información de la tabla nombreTabla: ( el nombre de cada columna, si los valores nulos se permiten o no (NULL or NOT NULL) en esa columna, tipo de dato de la columna, por ejemplo, NUMBER, CHAR, VARCHAR2, LONG, DATE, RAW, o LONG RAW, y la precisión de la columna si el tipo de dato lo requiere).

Otras informaciones disponibles en el catálogo del sistema (el comando DESCRIBE se basa en algunas de las tablas que se utilizan aquí) son:

select distinct table_name, column_name from all_cons_columns where OWNER='BD1TABLAS';

select * from all_cons_columns where OWNER='BD1TABLAS'; select OWNER, TABLE_NAME, COLUMN_NAME, DATA_TYPE, DATA_LENGTH,

DATA_PRECISION, DATA_SCALE from all_tab_columns where OWNER='BD1TABLAS';

Donde BD1TABLAS es un usuario (el propietario, en este caso, de la BD PROVEEDORES)

Para que los datos se muestren en pantalla sin saltos de línea, se puede dar formato a las columnas con las siguientes órdenes, (es permanente para toda la sesión, sólo se ejecutan una vez; si se quiere otro formato, hay que volver a ejecutarlas con las modificaciones oportunas)

COLUMN OWNER FORMAT a20 COLUMN CONSTRAINT_NAME FORMAT A20 COLUMN TABLE_NAME FORMAT A15 COLUMN COLUMN_NAME FORMAT A20

Page 8: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

8

COLUMN POSITION FORMAT 99 COLUMN DATA_TYPE FORMAT A15

Y también:

SET LINESIZE 600 (para evitar que la filas de salida, incluída la cabecera, ocupen , más de una línea)

SET PAGESIZE 200 (para evitar cabeceras tantas cabeceras)

Sobre guardar órdenes en disco

En la máquina se dispone de un disco duro local que se puede utilizar para guardar y recuperar ficheros generados por el alumno. No obstante, no se garantiza que los datos ahí guardados permanezcan de una sesión para otra. Por lo tanto, si se quieren guardar datos con seguridad es preferible hacerlo en un disco removible, o bien utilizando los servicios de disco virtual de la EPS o el Campus Virtual.

Page 9: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

9

select 1

SQL - SELECT Objetivos:

• Introducir al alumno en el SQL y la orden SELECT. • Comentar el esquema lógico propuesto.

Contenidos:

• Sistema de información propuesto. • La orden SELECT-FROM-WHERE. • Proyecciones, Selecciones. • Tipos de datos. • ORDER BY

Se proporciona información sobre las consultas más sencillas a realizar sobre una BD.

LA ORDEN SELECT-FROM-WHERE

Sintaxis general de la orden select

SELECT [ DISTINCT ] listaColumnas FROM listaTablas [ WHERE condición ] [ GROUP BY listaColumnas [ HAVING condición ] ] [ ORDER BY listaColumnas [ ASC | DESC ] ]

Select-From Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con

la sintaxis que se muestra en el punto anterior seremos capaces de formular cualquier requerimiento (consulta) sobre las tablas que componen una determinada BD. En este momento veremos la expresión mínima de la orden, formada por dos cláusulas, select y from, que obligatoriamente tendremos que especificar en cada consulta que realicemos.

Supongamos que sobre la base de datos Ejemplo (cuyo esquema y contenido se presentaron en la sesión anterior) queremos obtener todos los datos acerca de los profesores. Debemos, en primer lugar, seleccionar la base de datos, y ejecutamos (en el Query-language) la siguiente orden

select * from profesores

resultado: dni nombre categoria 21111222 EVA GOMEZ TEU 21222333 MANUEL PALOMAR TEU 21333444 RAFAEL ROMERO ASO6

Page 10: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

10

Al especificar en la lista de atributos un asterisco le indicamos al SGBD que deseamos la información de todas las columnas definidas para la tabla PROFESORES.

Si deseamos conocer a qué categorías pertenecen los profesores que se encuentran en la BD: select categoria from profesores

resultado: categoria TEU TEU ASO6

Podemos especificar tantas columnas como queramos:

select nombre, categoria from profesores

resultado: nombre categoria EVA GOMEZ TEU MANUEL PALOMAR TEU RAFAEL ROMERO ASO6

Para evitar la salida de filas duplicadas podemos utilizar el modificador DISTINCT:

select distinct categoria from profesores

resultado: categoria TEU ASO6

Nótese, sin embargo, que las dos órdenes siguientes obtienen el mismo resultado, puesto que la duplicación se refiere a filas completas y no a una columna en particular:

select distinct dni, categoria from profesores

select dni, categoria from profesores

resultado: dni categoria 21111222 TEU 21222333 TEU 21333444 ASO6

La cláusula WHERE

Con la orden select-from obtenemos la información de las columnas requeridas de toda la tabla. Si únicamente queremos información de aquellas filas que cumplen una determinada condición utilizaremos la cláusula where.

Pretendemos obtener el nombre de los profesores titulares:

select nombre from profesores where categoria = 'TEU'

resultado: nombre EVA GOMEZ MANUEL PALOMAR

Page 11: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

11

En la construcción de tales condiciones podemos utilizar las conectivas lógicas AND, OR, y NOT, así como los paréntesis para alterar la evaluación de izquierda a derecha. También, los operadores de comparación >, <, >=, <=, <>

Nombre de los profesores que son titulares o asociados a 6 horas:

select nombre from profesores where categoria = 'TEU' or categoria = 'ASO6'

resultado: nombre EVA GOMEZ MANUEL PALOMAR RAFAEL ROMERO

La cláusula ORDER BY

Podemos ordenar la salida producida por nuestra orden select por valores ascendentes o descendentes de una columna en particular.

Nombre de las asignaturas ordenadas de menor a mayor número de créditos:

select creditos, descripcion from asignaturas order by creditos

resultado: creditos descripcion 4.5 Historia de la Informática 6 Fundamentos de las Bases de Datos 6 Diseño y Gestión de Bases de Datos 6 Programación Concurrente 9 Fundamentos de la Programación

Si no se indica nada la ordenación será ascendente.

El mismo requerimiento anterior pero en orden descendente y de aquellas que tienen más de 4.5 créditos:

select creditos, descripcion from asignaturas where creditos > 4.5 order by creditos desc

resultado: creditos descripcion 9 Fundamentos de la Programación 6 Fundamentos de las Bases de Datos 6 Diseño y Gestión de Bases de Datos 6 Programación Concurrente

Puede aplicarse más de un criterio de ordenación:

select creditos, descripcion from asignaturas order by creditos, descripcion

resultado: creditos descripcion 4.5 Historia de la Informática 6 Diseño y Gestión de Bases de Datos 6 Fundamentos de las Bases de Datos 6 Programación Concurrente 9 Fundamentos de la Programación

Page 12: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

12

Constantes

Se pueden explicitar constantes en la orden select de forma que dicho valor aparezca en todas las filas:

select 'La asignatura ', descripcion, ' tiene ', creditos, ' creditos' from asignaturas order by creditos

resultado: 'laasignatura' descripcion 'tiene' creditos 'créditos’ La asignatura HISTORIA DE LA INFORMATICA tiene 4.5 créditos La asignatura FUNDAMENTOS DE LAS BASES DE DATOS tiene 6 créditos La asignatura DISEÑO Y GESTION DE BASES DE DATOS tiene 6 créditos La asignatura PROGRAMACION CONCURRENTE tiene 6 créditos La asignatura FUNDAMENTOS DE LA PROGRAMACION tiene 9 créditos

Page 13: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

13

BD Proveedores

LA BASE DE DATOS PROVEEDORES

Objetivos:

• Ser capaz de interpretar un esquema de base de datos relacional (concretamente, el propuesto para las prácticas de la asignatura: Proveedores)

Se detalla el esquema lógico que describe la BD de PROVEEDORES, ya creada y a disposición del alumno, intentando que comprenda su significado, el sistema real que pretende representar. El esquema lógico es la referencia que permite construir las órdenes select con las que interrogar a la BD. Las extensiones de cada relación se incluyen como ayuda para comprobar la corrección de las órdenes select utilizadas.

Page 14: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

14

LA BASE DE DATOS PROVEEDORES

TABLA COLUMNAS RESTRICCIONES VENDEDOR ( numvend NUMBER(4),

nomvend VARCHAR2(30), nombrecomer VARCHAR2(30), telefono CHAR(11), calle VARCHAR2(30), ciudad VARCHAR2(20), provincia VARCHAR2(20) )

Clave Primaria: (numvend)

PIEZA ( numpieza VARCHAR2(16), nompieza VARCHAR2(30), preciovent NUMBER(9,2))

Clave Primaria: (numpieza)

PRECIOSUM ( numpieza VARCHAR2(16), numvend NUMBER(4), preciounit NUMBER(9,2), diassum NUMBER(3), descuento NUMBER(2))

Clave Primaria: (numpieza, numvend) Clave Ajena: (numpieza)→ PIEZA, Clave Ajena: (numvend)→ VENDEDOR

PEDIDO ( numpedido NUMBER(5), numvend NUMBER(4), fecha DATE )

Clave Primaria: (numpedido) Clave Ajena: (numvend)→ VENDEDOR

LINPED ( numpedido NUMBER(5), numlinea NUMBER(2), numpieza VARCHAR2(16), preciocompra NUMBER(9,2), cantpedida NUMBER(4), fecharecep DATE, cantrecibida NUMBER(4))

Clave Primaria: (numpedido, numlinea) Clave Ajena: (numpedido)→ PEDIDO Clave Ajena: (numpieza)→ PIEZA

INVENTARIO ( numpieza VARCHAR2(16), numbin NUMBER(10), cantdisponible NUMBER(5), fecharecuento DATE, periodorecuen NUMBER(2), cantminima NUMBER(5) )

Clave Primaria: (numbin) Clave Alternativa: (numpieza) Clave Ajena: (numpieza)→ PIEZA

La base de datos pretende reflejar la política de compras de una empresa de distribución. Se compran (tablas PEDIDO y LINPED) ciertas mercancías a los distintos proveedores (tabla VENDEDOR) y son vendidas posteriormente al público o a otros distribuidores (que no hemos considerado en la BD)

Básicamente, las tareas que se pretenden mecanizar son las siguientes (entre paréntesis aparecen las tablas directamente relacionadas con cada una):

• Lista de suministradores (vendedor).

Los datos de los proveedores que nos suministran la mercadería que, posteriormente, es vendida al público en general.

• Catálogo de venta (pieza)

Las piezas que distribuye nuestra empresa y el precio de venta al público de las mismas.

Page 15: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

15

• Lista de precios de suministro (preciosum, vendedor, pieza).

Conocer los precios a los que los proveedores nos podrían suministrar las piezas. Es información histórica cuyo origen no nos preocupa. No se debe confundir esta información con la de los pedidos: los artículos almacenado en preciosum puede que no se hayan pedido nunca y, si se ha hecho, que hayan sido comprados a un precio distinto porque se negociara en ese instante con cualquiera de los suministradores.

• Control de pedidos (pedido, linped, vendedor, pieza).

De aquellas mercancías que se solicitan a los proveedores, controlar si se han servido en el tiempo estimado y en la cantidad pedida.

Cada pedido consta de: • Cabecera de pedido (tabla pedido), donde se especifica qué vendedor nos ha

suministrado el pedido completo, y la fecha en que se realizó el pedido.

• Líneas de pedido (tabla linped), donde un conjunto de líneas pertenecientes a un mismo pedido se numeran desde la número 1 en adelante. Contiene el código de pieza que sirvió el proveedor, la cantidad que se le pidió y la cantidad que realmente ha servido a nuestra empresa y la fecha en la que se recibió, así como el precio al que se le compro (puede ser diferente al estipulado en preciosum).

Sólo aquellas piezas que aparezcan en una línea de pedido han sido solicitadas al correspondiente vendedor y, si la cantidad recibida es mayor que cero, habrán sido recibidas por la empresa en esa cantidad.

• Control de existencias (inventario, pieza).

Mediante la confección de un inventario, donde cada entrada, que corresponde a un único artículo, es el recuento real de existencias.

Page 16: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

16

tabla VENDEDOR

numvend nomvend nombrecomer telefono calle Ciudad provincia

1 AGAPITO LAFUENTE DEL CORRAL MECEMSA 96-5782401 Avda. Valencia 3205 ALICANTE ALICANTE

2 LUCIANO BLAZQUEZ VAZQUEZ HARW S.A. 96-3232321 GENERAL LACY, 15 2

B ALICANTE ALICANTE

3 GODOFREDO MARTIN MARTINEZ MECEMSA 96-4141722 AVDA. VALENCIA 3372 ALICANTE ALICANTE

4 JUANITO REINA PRINCESA HARW S.A. 903-696969 DONDEQUIERAS,

1000, 13F LO ANGELE LOS EU'S

5 JUANITO REINA PRINCESA LA DEAQUI 98-5363636 S. FRANCISCO DE

ASIS, 10 1 GIJON ASTURIAS

6 MANOLO PIEDRA POMEZ HUMP S.A. 96-5660727 AVIACION 92, 3 I SAN VICENTE ALICANTE

7 MANUEL PEREZ RODRIGUEZ

SOFTHARD DISTRIBUIDORA S.A. 98-5696969 ARZOBISPO LOACES QUINTANAR DE LA

ORDE TOLEDO

8 LUISA PINTO HEREDIA LA MEJOR S.A. 999-2014455 OXFORD BLUES NEW ORLEANS LOUISSIANA 9 CHEMA PAMUNDI OLE ESPAÑA, S.A. RIVAS VACIAMADRID MADRID 10 GUSTAVO DE BASICA OLE ESPAÑA, S.A. RIVAS VACIAMADRID MADRID

11 MARIO DUQUE LIZONDO BANESTOESSOFT S.L. 98-0101010 MOROS, 19 GIJON ASTURIAS

12 JOSE ANTONIO MARTINEZ JUAN OLE ESPAÑA, S.A. 3667788 COLON, 21 VALENCIA VALENCIA

13 MANUEL GOMEZ SANTISTEBAN OLE ESPAÑA, S.A. 3667789 COLON, 21 VALENCIA VALENCIA

8001 JUAN RODRIGUEZ JUAN HALA S.A. ALMORADI ALICANTE

8002 JUAN MARTINEZ GARCIA HARW S.A. 3334455 CISCAR, 5 VALENCIA VALENCIA

8003 LUIS RODRIGUEZ SALA HARW S.A. 3335588 SALAMANCA, 102 VALENCIA VALENCIA

100 PEDRO GRACIA MORALES SOFT S.A. SALAMANCA, 100 VALENCIA VALENCIA

101 SALVADOR PLA GARCIA TABAC & SOFT 5661100 MAYOR, 44 SAN VICENTE ALICANTE

102 SOLEDAD MARTINEZ ORTEGA ASX. S.A. 87879998 PEREZ GALDOS, 54 ALICANTE ALICANTE

200 SEVERINO MARTIN MARTINEZ SEVESOFT 5779988 GENERAL LACY, 17 ALICANTE ALICANTE

55 LUIS GARCIA SATORRE HARW S.A. 5889944 POETA ALONSO, 12 ALICANTE ALICANTE

201 MANUEL ORTUÑO LAFUENTE HALA S.A. 5660788 MAYOR, 64 SAN VICENTE ALICANTE

tabla PIEZA numpieza nompieza preciovent A-1001-L MOUSE ADL 3B 7,00 C-1002-H 4,00 C-1002-J 7,00 C-400-Z FILTRO PANTALLA X200 18,00

DD-0001-210 DISCO DURO WESTERN DIG 210M 28 250,00 DD-0001-30 DISCO DURO 30M SEAGATE 200,00 DK144-0001 DISKETTE 1.44 PANASONIC 1,10

DK144-0002-P PACK DISKETTE 144 PANASONIC 10,00 FD-0001-144 FLOPPY 1.44 IBM 180,00 FD-0002-720 FLOPPY 720K IBM 150,00

M-0001-C MONITOR SYNCMASTER 3 COLOR 170,00 M-0002-C MONITOR COLOR SONY BT 350,00 M-0003-C MONITOR IBM 3570 COLOR 400,00 O-0001-PP PEGATINAS CONCIERTO JEVI 20,00 O-0002-PP PACK PEGATINAS CONCIERTO JEVI 100,00 P-0001-33 PLACA INTEL 33Mz 350,00

T-0001-IBM TECLADO XT IBM 110,00 T-0002-AT TECLADO AT SUSUSU 55,00 T-0003-AT TECLADO AT HP 120,00 X-0001-PC TECLADO ESTANDAR PC 70,00

Page 17: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

17

tabla PEDIDO numpedido numvend fecha

1 1 05/05/1992 2 1 11/10/1992 3 2 15/10/1992 4 2 16/10/1992 5 1 22/10/1992 6 5 22/08/1995 7 8002 02/10/1992

tabla LINPED numpedido numlinea numpieza preciocompra cantpedida fecharecep cantrecibida

1 1 M-0001-C 300,00 10 10/05/1992 10 1 2 P-0001-33 210,00 20 10/05/1992 18 1 3 FD-0001-144 135,00 20 10/05/1992 20 1 4 DD-0001-210 150,00 20 10/05/1992 20 1 5 T-0002-AT 31,00 22 17/10/1992 22 2 1 DK144-0002-P 5,45 100 15/10/1992 101 2 2 T-0002-AT 30,00 1 15/10/1992 1 3 1 DD-0001-210 146,00 15 17/10/1992 15 3 2 P-0001-33 210,00 3 17/10/1992 3 4 1 O-0002-PP 99,00 10 17/10/1992 10 5 1 T-0002-AT 15,00 15 11/06/1993 13 6 1 O-0001-PP 15,00 1000 25/08/1995 1000 6 2 O-0002-PP 99,00 2000 25/08/1995 1998 7 1 C-400-Z 7,00 45 09/10/1992 8

tabla INVENTARIO numpieza numbin cantdisponible fecharecuento periodorecuen cantminima

DD-0001-30 1 120 15/10/1990 1 15 P-0001-33 2 10 15/10/1992 5 O-0002-PP 3 110 15/10/1992 1 3 M-0001-C 4 15 15/10/1992 2 2 M-0003-C 5 2 20/10/1992 1 0

DD-0001-210 6 10 12/11/1992 2 1 FD-0001-144 7 10 12/11/1992 2 0

Page 18: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

18

tabla PRECIOSUM numpieza numvend preciounit diassum descuento A-1001-L 3 5,00 1 A-1001-L 4 4,90 1 A-1001-L 100 4,00 3 A-1001-L 1 2,00 3 C-1002-H 1 0,50 2 C-1002-J 1 1,50 2 C-400-Z 1 8,50 4 5 C-400-Z 8002 7,00 3

DD-0001-210 1 150,00 3 15 DD-0001-210 2 170,00 5 12 DD-0001-210 101 140,00 15 14 DD-0001-30 1 120,00 4 DK144-0001 1 0,56 3

DK144-0002-P 1 5,60 3 DK144-0002-P 2 5,50 5 FD-0001-144 1 130,00 3 FD-0001-144 102 136,00 3 7 FD-0001-144 55 120,00 10 13 FD-0002-720 1 60,00 3

M-0001-C 1 155,00 3 10 M-0001-C 3 180,00 7 15 M-0002-C 9 300,00 1 5 M-0002-C 1 150,00 10 15 M-0003-C 3 350,00 2 15 M-0003-C 4 280,00 7 M-0003-C 1 200,00 7 O-0001-PP 5 19,50 1 O-0001-PP 55 15,00 7 O-0001-PP 1 15,00 1 O-0002-PP 2 99,00 1 O-0002-PP 5 98,75 1 12 O-0002-PP 101 80,00 10 O-0002-PP 1 75,00 1 P-0001-33 2 210,00 5 P-0001-33 1 250,00 3 P-0001-33 4 280,00 7 P-0001-33 3 250,00 2 P-0001-33 5 280,00 3 10

T-0001-IBM 2 90,00 5 T-0001-IBM 100 95,00 5 10 T-0001-IBM 1 90,00 15 T-0002-AT 1 30,00 3 T-0002-AT 2 35,00 5 7 T-0002-AT 4 25,00 7 T-0002-AT 5 33,00 3 T-0002-AT 100 34,00 2 5 T-0002-AT 201 30,00 1 5 T-0003-AT 1 77,50 3 T-0003-AT 3 81,45

Page 19: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

19

CONSULTAS SELECT1

1. Obtener todos los números de piezas de las piezas de la base de datos.

2. Nombre de todas las piezas con un precio de venta menor que 1000.

3. Número, nombre y precio de venta de las piezas de precio de venta mayor que 10 o menor que 1 euros, ordenadas de menor a mayor precio.

4. Para cada pieza de la que se conozca algún suministrador, obtener el número de pieza y el descuento, en orden descendente del valor de descuento.

5. Nombre de los vendedores con número de vendedor menor que 6.

6. Modificar el requerimiento anterior para eliminar duplicados.

7. Número y nombre de los vendedores con número de vendedor menor que 6.

8. Obtener todos los números de los vendedores de los que se sepa que pueden suministrar alguna pieza.

9. Vendedores de la provincia de Alicante.

10. Nombre y empresa de los vendedores de la Comunidad Valenciana.

11. Números de vendedores y días que tardarían en suministrar la pieza 'P-0001-33'

12. Códigos de pieza solicitados en el pedido 1, ordenados de mayor a menor precio de compra.

13. Números de pedido y números de vendedor, para los pedidos solicitados el 15 de octubre de 1992.

14. Códigos de pieza de los que se sabe que algún vendedor nos podría hacer descuento.

15. Códigos de pieza, de posible suministrador y precio de suministro, ordenados por código de vendedor y código de pieza.

Page 20: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

20

Page 21: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

21

select 2

CONSULTAS SOBRE VARIAS TABLAS

Objetivos:

• Poder relacionar distintas tablas de la BD para obtener información más compleja.

Contenidos

• Utilización de más de una tabla. • Nombres cualificados de atributo. • Sinónimos temporales de tabla. • Tipos de datos: dominios. • Resolución de requerimientos

UTILIZACIÓN DE MÁS DE UNA TABLA Para la resolución de la mayoría de requerimientos es necesario trabajar con información que

se obtiene de relacionar varias tablas. La forma de especificar qué tablas vamos a consultar es construir una lista de nombres de tablas en la cláusula FROM.

Si seleccionamos la BD Ejemplo, podemos preguntar por el nombre de los profesores y la descripción de las asignaturas que imparten; esta información se encuentra almacenada en la tabla imparte, que relaciona las claves primarias de cada una de las tablas asociadas por tal relación.

select nombre, descripcion from asignaturas, imparte, profesores where profesores.dni = imparte.dni and asignatura = codigo

resultado: nombre descripcion EVA GOMEZ Fundamentos de las Bases de Datos EVA GOMEZ Diseño y Gestión de Bases de Datos RAFAEL ROMERO Programación Concurrente

En primer lugar, solicitamos nombre (del profesor) y descripcion (de la asignatura). El primer atributo se encuentra en la tabla profesores, y el segundo en la de asignaturas. La relación entre ambas tablas se encuentra en la tabla imparte, que asocia dni de profesor con codigo de asignatura que imparte. Así, para obtener la información que precisamos, necesitamos involucrar a las tres tablas al mismo tiempo.

Podemos pensar, por clarificar el mecanismo por el que se obtiene este resultado, que el SGBD recorre la tabla de profesores, tupla por tupla, y busca el valor de dni de cada una en la tabla imparte. Si encuentra tal valor, en esa tupla de imparte en que lo ha encontrado, aparecerá el código de asignatura, en la columna nominada como asignatura; buscando en la tercera tabla, asignaturas, obtendrá la descripcion y finalmente mostrará en pantalla el nombre y la descripción que le corresponde.

Page 22: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

22

Nótese que no aparece MANUEL PALOMAR, o la asignatura HISTORIA DE LA INFORMÁTICA, puesto que ni el primero (en nuestra BD) imparte asignatura alguna, ni la segunda es impartida por ningún profesor (de los conocidos por nuestro sistema).

¿Qué pasaría si no utilizáramos la cláusula where para enlazar las tablas? Supongamos el siguiente requerimiento:

select asignatura, nombre from profesores, imparte

resultado: asignatura nombre FBD EVA GOMEZ FBD MANUEL PALOMAR FBD RAFAEL ROMERO DGBD EVA GOMEZ DGBD MANUEL PALOMAR DGBD RAFAEL ROMERO PC EVA GOMEZ PC MANUEL PALOMAR PC RAFAEL ROMERO

Si no indicamos nada en la cláusula where la información que obtenemos es simplemente la combinación de cada tupla con todas las demás: si hay 3 tuplas en imparte y otras 3 en profesores, la cardinalidad de la relación resultante es 3 x 3 = 9 tuplas. Si en la cláusula from pusiéramos, además, la tabla asignaturas, el resultado final tendría 3 x 3 x 5 = 45 tuplas.

Veamos en detalle como funciona la orden select-from-where para el caso de la siguiente consulta (códigos de asignaturas y nombre de los profesores que las imparten)1:

select asignatura, nombre from profesores, imparte where profesores.dni = imparte.dni

resultado: asignatura nombre FBD EVA GOMEZ DGBD EVA GOMEZ PC RAFAEL ROMERO

El SGBD primero combinaría todas las tuplas con todas de las tablas especificadas en el from:

dni nombre categoria ingreso dni asignatura 21111222 EVA GOMEZ TEU 01/10/1993 21111222 FBD 21222333 MANUEL PALOMAR TEU 16/06/1989 21111222 FBD 21333444 RAFAEL ROMERO ASO6 16/06/1992 21111222 FBD 21111222 EVA GOMEZ TEU 01/10/1993 21111222 DGBD 21222333 MANUEL PALOMAR TEU 16/06/1989 21111222 DGBD 21333444 RAFAEL ROMERO ASO6 16/06/1992 21111222 DGBD 21111222 EVA GOMEZ TEU 01/10/1993 21333444 PC 21222333 MANUEL PALOMAR TEU 16/06/1989 21333444 PC

21333444 RAFAEL ROMERO ASO6 16/06/1992 21333444 PC

1 Esto no es necesariamente real, una de las ventajas de utilizar un SGBD es que las consultas se procesan de manera eficiente y de forma totalmente transparente para el usuario.

Page 23: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

23

Por lo especificado por la where eliminaría aquellas tuplas que no cumplieran la condición, y nos quedaría:

dni nombre categoria ingreso dni asignatura 21111222 EVA GOMEZ TEU 01/10/1993 21111222 FBD 21111222 EVA GOMEZ TEU 01/10/1993 21111222 DGBD

21333444 RAFAEL ROMERO ASO6 16/06/1992 21333444 PC

Y por último, las columnas especificadas en la select determinarían el resultado final:

asignatura nombre FBD EVA GOMEZ DGBD EVA GOMEZ

PC RAFAEL ROMERO

NOMBRES CUALIFICADOS DE ATRIBUTO Si observamos la sentencia select anterior, al comparar los dni que aparecen en profesores y

en imparte hemos utilizado el nombre de la tabla a la que pertenecen cada uno, profesores.dni e imparte.dni.

Si en el conjunto de columnas de todas las tablas que se especifican en la cláusula from existen varias con nombres iguales, deberemos especificar en todo momento la tabla de la que queremos extraer la información. Caso de no existir ambigüedad, no es necesario utilizar el nombre de la tabla; ni asignatura ni codigo se utilizan en otras tablas.

Si deseamos conocer el dni y el nombre de los profesores que imparten alguna asignatura, buscaremos en imparte los dni de los profesores (son los que tienen al menos una asignatura asignada), y con este valor obtendremos el nombre en profesores.

select dni, nombre from profesores, imparte where profesores.dni = imparte.dni

resultado: ERROR

Al especificar que nos muestre en pantalla el dni del profesor, el SGBD entra en conflicto puesto que no sabe si nos referimos al de la tabla profesores o al de la tabla imparte. Utilizaremos el nombre completo de la columna (es indiferente, en este caso, de qué tabla):

select profesores.dni, nombre from profesores, imparte where profesores.dni = imparte.dni

resultado: dni nombre 21111222 EVA GOMEZ 21111222 EVA GOMEZ 21333444 RAFAEL ROMERO

Se recuerda que la ocurrencia EVA GOMEZ está relacionada con dos asignaturas, y es por eso que aparece duplicada en este resultado. La forma de evitar tuplas idénticas ya se mostró en la sesión anterior.

Page 24: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

24

SINÓNIMOS TEMPORALES DE TABLA Para facilitar la escritura de las sentencias select (entre otros posibles motivos) se pueden

utilizar alias temporales, nombres alternativos de las tablas. Se especifican en la lista de tablas del from, antes de la “,” que separa el nombre de la tabla en cuestión de la siguiente.

select distinct p.dni, nombre from profesores p, imparte i where p.dni = i.dni

resultado: dni nombre 21111222 EVA GOMEZ 21333444 RAFAEL ROMERO

CONSULTAS SELECT2

1. Obtener el número de pieza junto con el nombre de todas las provincias desde las que puede sernos suministrada, en orden descendente del número de pieza.

2. Modificar el requerimiento anterior para eliminar duplicados.

3. Lista el nombre y número de las piezas.

4. Obtener el nombre y número de proveedores de la provincia de Valencia.

5. Obtener el nombre y número de proveedores de la provincia de Valencia a los que se les ha solicitado un pedido.

6. Obtener los números de línea y su precio de compra del pedido número 1.

7. Obtener todas las piezas que se recuenten el 15 /10/1992.

8. Obtener número y nombre de todas las piezas recibidas el 1 de Mayo de 1992.

9. Precio unitario de suministro del número de pieza A-1001-L y el vendedor 100.

10. Nombres de proveedores que puedan suministrarnos la pieza numero A-1001-L

11. Obtener nombre, teléfono, y ciudad del vendedor que puede suministrarnos piezas con valor mayor de 100.

12. Obtener los vendedores que pueden suministrarnos piezas con un descuento de más de 10%.

13. Obtener los números de pedido del vendedor número 1.

14. Obtener los vendedores ordenados alfabéticamente en orden descendente.

15. Ídem en orden ascendente.

16. Obtener los números de pieza de las que conozcamos algún vendedor que nos la pueda suministrar.

17. Número y nombre de las piezas que puedan suministrarnos el vendedor número 2 y el 4 (no necesariamente que las puedan suministrar los dos).

18. Piezas que nos puedan suministar los vendedores de la empresa Harw S.A.

Page 25: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

25

19. Número, nombre y precio de venta de las piezas que han sido compradas en un pedido servido por el vendedor 1.

20. Número y nombre de vendedor, y pieza que ha sido comprada a un precio mayor que el estipulado en la lista de precios de suministro.

21. Número de pieza y número y nombre de vendedor de aquellas piezas cuyo precio de venta es mayor que 50 o su descuento de suministro es mayor que 10.

22. Pedidos y datos del vendedor cuya fecha de pedido no sea el 22 de octubre de 1992.

23. Precios a los que nos pueden ser suministradas las piezas DD-0001-210 y FD-0001-144, y número y nombre de los vendedores que las podrían suministrar a esos precios.

Page 26: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

26

Page 27: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

27

select 3

EXPRESIONES DE SELECCIÓN DE FILAS

Objetivos:

• Comparaciones de cadenas de caracteres.

Contenidos

• BETWEEN, IN • LIKE, subcadenas.

Construcción de expresiones de selección de filas utilizando rangos, listas, y funciones de comparación de cadenas de caracteres.

RANGOS Expresiones del tipo 10 <= x <= 100 se pueden construir utilizando el operador de

construcción de rangos BETWEEN.

La sintaxis de tal subexpresión de la cláusula where es la siguiente:

expresión [NOT] BETWEEN expresión AND expresión

Por ejemplo, deseamos conocer los créditos y descripción de las asignaturas cuyo número de créditos está entre 5 y 8.

select creditos, descripcion from asignaturas where creditos between 5 and 8

resultado: creditos descripcion 6 Fundamentos de las Bases de Datos 6 Diseño y Gestión de Bases de Datos 6 Programación Concurrente

LISTAS Mediante el operador IN se puede buscar un determinado valor en una lista construida usando

constantes.

expresión [NOT] IN (listaValores)

Page 28: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

28

Descripción de las asignaturas FBD y DGBD:

select descripcion from asignaturas where codigo in ('FBD', 'DGBD')

resultado: descripcion Fundamentos de las Bases de Datos Diseño y Gestión de Bases de Datos

Nombre de los profesores que no imparten HI, FBD o DGBD:

select nombre from profesores p, imparte i where p.dni = i.dni and asignatura not in ('HI', 'FBD', 'DGBD')

resultado: nombre RAFAEL ROMERO

Fijémonos en que MANUEL PALOMAR, que no imparte ninguna de las asignaturas objeto de la búsqueda, tampoco aparece en la tabla resultado puesto que su dni no aparece en la tabla IMPARTE.

SUBCADENAS DE CARACTERES Podemos preguntar por subcadenas dentro de columnas de tipo carácter. Para ello utilizaremos

los operadores LIKE o MATCHES, que soportan la siguiente sintaxis:

columna [NOT] LIKE 'cadena'

La cadena de caracteres cadena admite los comodines % y _ , equivalentes en uso a los comodines de MS-DOS * y ?, es decir, el primero indica una cadena de caracteres de cualquier longitud, y el segundo un carácter cualquiera.

Profesores que atiendan al nombre de 'RAFA':

select * from profesores where nombre like 'RAFA%'

resultado: dni nombre categoria 21333444 RAFAEL ROMERO ASO6

Código de las asignaturas de 'Bases de Datos'

select codigo from asignaturas where descripcion like '%BASES DE DATOS%'

resultado: codigo FBD DGBD

Page 29: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

29

Código de las asignaturas, siendo tal código de 2 caracteres:

select codigo from asignaturas where codigo like '__ '

(2 subrayados seguidos de 3 espacios en blanco: codigo es un CHAR(5)

resultado: codigo HI PC FP

VALORES NULOS Podemos interrogar a la BD de datos en busca de valores desconocidos

(información faltante) mediante el operador IS NULL, cuya sintaxis es:

columna IS [NOT] NULL

Código y créditos de las asignaturas de las que conocemos su número de créditos:

select codigo, creditos from asignaturas

where creditos is not null

resultado: codigo creditos HI 4.5 FBD 6 DGBD 6 PC 6 FP 9

RESUMEN DE OPERADORES Recopilamos todos los operadores y conectivas lógicas vistos hasta ahora para la construcción

de expresiones condicionales:

= AND BETWEEN LIKE {%,_} > OR IN < NOT

> = < = < >

IS NULL

Page 30: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

30

CONSULTAS SELECT3

1. Obtener el nombre de las piezas que puedan ser suministradas por aquellos proveedores cuyo nombre empiece por S.

2. Obtener el nombre de las piezas que puedan ser suministradas por proveedores cuyo nombre empiece por S, y se llamen de apellido2 Martínez o Martín.

3. Obtener los nombres de los vendedores de las provincias de Valencia, Castellón o Alicante.

4. Nombres de vendedores que empieza su nombre por J.

5. Nombres de vendedores que termina su nombre por Z.

6. Nombres de vendedores que se apellidan López.

7. Nombre de vendedores que el nombre empieza por M seguido de cualquier carácter simple, una R y cualquier cadena de n caracteres.

8. Obtener los vendedores de la provincia de Valencia o Alicante que su nombre empieza por J o por M y tienen un número de vendedor entre 1 y 100.

9. Listar los nombres y números de vendedores así como el número y nombre de las piezas que pueden suministrar, para los vendedores de la provincia de Valencia o Alicante.

10. Obtener los nombres de pieza que pueden suministrar los vendedores de apellido 'García'.

11. Piezas3 que sabemos que nos puede suministrar algún vendedor.

12. Obtener todos los vendedores que tengan teléfono.

13. Listar las piezas con un descuento entre 1 y 10 cuyo nombre contenga una O y que se las hayamos solicitado a proveedores cuyo número oscile entre el 1 y el 1000.

14. Obtener los nombres de vendedores en orden alfabético.

15. Obtener nombre de vendedores y nombre de piezas que pueden suministrar ordenado en orden alfabético.

16. Obtener todos los nombres de piezas que pueda suministrar el vendedor 100, el 300 y/o el 400 con un precio de venta entre 10 y 1000, y un precio unitario entre 1 y 500.

17. Obtener el número de pieza y el precio de los monitores.

18. Nombre de las piezas que pueden sernos suministradas desde la Comunidad Valenciana.

19. Obtener los vendedores que viven en la calle Ciscar o Salamanca y de la Empresa Harw S.A.

20. Obtener nombres de vendedores y números de pieza que nos pueden suministrar, de aquellos vendedores cuyo apellido comienza por Martín, y ordenados alfabéticamente.

2 Evidentemente, la BD no diferencia entre nombre y apellido primero y segundo, por lo que se ha de tratar como subcadenas dentro del valor del atributo.

3 Cuando no se especifica un atributo concreto, se entiende que se pide toda la información disponible en la BD de los objetos solicitados.

Page 31: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

31

select fecha

FUNCIONES DE FECHA4 Objetivos:

• Construir condiciones de selección de filas utilizando atributos de tipo fecha.

Contenidos

• TO_CHAR() • TO_DATE() • SYSDATE • ADD_MONTHS() • MONTHS_BETWEEN()

FUNCIONES DE FECHA Se presentan a continuación distintas funciones de manejo de fechas y hora, que se pueden

utilizar tanto en la lista de columnas que aparecerán en la tabla resultado de la select como en la construcción de expresiones de la where.

En general, la comparación entre fechas se hace directamente. Por ejemplo:

select nombre from profesores where ingreso < '23/12/1989';

select nombre from profesores where ingreso < '23/12/1989'’

resultado: nombre MANUEL PALOMAR

Pero si necesitamos hacer transformaciones sobre un determinado dato (extraer parte de una fecha, cambiar el formato de visualización, calcular días, etc.) entonces debemos ayudarnos de estas funciones.

TO_CHAR(fecha [, formato]) Convierte la fecha de tipo DATE a un valor VARCHAR2 en el formato especificado en "formato"

TO_DATE(cadena [, formato])Convierte la cadena de caracteres "cadena" de tipo CHAR a un valor de tipo DATE con el formato especificado en "formato"

SYSDATE Devuelve la fecha actual del sistema

ADD_MONTHS(fecha,n) Devuelve la fecha especificada con n meses más

MONTHS_BETWEEN(fecha1,fecha2) Devuelve los meses transcurridos entre fecha1 y fecha2

4 Aunque todas las demás sesiones de prácticas cumplen con el estándar SQL, los tipos de datos de fecha y hora y las funciones que los manejan no suelen estar igualmente implementadas en todos los SGBD, por lo que esta sesión es únicamente aplicable a Oracle.

Page 32: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

32

FORMATOS DE FECHA Las funciones TO_CHAR() y TO_DATE() admiten distintos formatos de fecha que se pueden

construir según una máscara especificada por el usuario. Dicha máscara es una cadena de caracteres entre comillas simples en la que se pueden utilizar los siguientes:

ELEMENTO SIGNIFICADO - / ' . ; : 'texto' Marcas de puntuación y texto fijo que se reproduce en el resultado D Día de la semana (1-7) DAY Nombre del día de la semana DD Día del mes (1-31) DY Día del año (1-366) MM Mes (1-12) MON Nombre abreviado del mes MONTH Nombre completo del mes Q Cuatrimestre del año (1-4) YYYY Año con 4 dígitos Y,YYY Año con punto de millar YY Año con 2 dígitos

Por ejemplo:

select nombre, to_char (ingreso,'DD') from profesores where to_char(ingreso,'DD') < 15

select * from profesores where to_char(ingreso,'MM') < 6

select * from profesores where ingreso = sysdate

Para obtener el número de días entre dos fechas basta con utilizar la operación resta

select nombre, sysdate-ingreso from profesores

CONSULTAS SELECT FECHA

1. Obtener el número de pieza de las piezas que se recuenten el 15/10/92.

2. Números de pieza de las piezas que se recuentan entre el 1 de Octubre de 1992 y el 31 de Octubre de 1992.

3. Número y fecha de los pedidos solicitados en el segundo semestre del 92.

4. Nombre de los vendedores que sirvieron piezas en la primera quincena de mayo del 92, ordenado alfabéticamente.

5. Número, nombre de vendedor y mes en que se les solicitó un pedido de discos duros.

6. Años en que se ha efectuado algún recuento.

7. Número y descripción de las piezas que sirvieron los proveedores los días 10 de cada mes.

8. Número y descripción de las piezas que sirvieron los proveedores en el 95 y cuyo precio de compra es superior al precio de suministro que ellos ofertaban.

9. Número de pieza, descripción, fecha de recepción, cantidad recibida, de las piezas recibidas en el 95 y de precio de venta entre 50 y 100 euros.

Page 33: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

create

DEFINICIÓN DE DATOS Objetivos:

• Introducir al alumno a la definición de datos.

Contenidos

• Las órdenes CREATE TABLE y DROP TABLE • Restricciones • La orden INSERT (1) • Información sobre las restricciones de una tabla

IMPORTANTE Para ésta y las sesiones que traten de crear y borrar tablas, e insertar, modificar o eliminar

datos, es necesario entrar al sistema con un usuario con permisos suficientes y diferente para cada puesto (si dos alumnos entraran con el mismo usuario estarían trabajando en el mismo espacio de trabajo y colisionarían al crear y mantener sus tablas). Por ello, se debe iniciar la sesión como:

usuario: bdixx contraseña: bdixx servicio: oracle

donde xx es el número del ordenador en el aula (01, 02, ..., 10, 11, ... 25 ...)

Dado que el número de usuarios es limitado, al terminar cada grupo de prácticas, los usuarios serán “limpiados” por lo que los datos manejados durante la sesión serán borrados y no estarán disponibles para las semanas siguientes.

LA ORDEN CREATE TABLE La definición de tablas es el primer paso en la creación de una base de datos. El conjunto de

descripciones de tablas conforma el esquema de base de datos y representa a un sistema de información concreto.

Supongamos que vamos a implementar un esquema de base de datos relacional de profesores, asignaturas (sólo es un listado de profesores y asignaturas, sin relaciones entre ellos). En primer lugar debemos decidir cuáles son los atributos de cada uno de ellos y sus tipos de datos:

PROFESORES (DNI: varchar2(10), nombre: varchar2(40), categoria: char(4), ingreso: datetime) ASIGNATURAS (codigo: char(5), descripcion: varchar2(35), creditos: number(3,1) creditosp: number(3,1))

Page 34: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior
Page 35: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

35

Para cumplir con las restricciones del modelo relacional, además, debemos elegir las claves primarias adecuadas5: DNI para profesores y codigo para asignaturas. Obviamente, la forma que tienen estas tablas ha sido una decisión nuestra como diseñadores de esta base de datos concreta, en otra situación hubiéramos, probablemente, decidido definir otros atributos y otras tablas.

La orden CREATE TABLE nos permite crear cada una de las tablas necesarias para nuestra base de datos:

CREATE TABLE nombreTabla ( {listaColumnas} [,{restricciones}] )

La lista de columnas, en su forma más sencilla, es un conjunto de expresiones (tantas como columnas deseemos, y separadas por comas) del tipo:

columna tipoDatos[,columna tipoDatos[, ...]]

RESTRICCIONES Las restricciones son reglas, que normalmente se establecen en el momento de crear una

tabla, para garantizar la integridad de los datos.

Básicamente, las restricciones obligan a cumplirse ciertas reglas cuando una fila es insertada, borrada o modificada, de forma que la operación se llevará a efecto sólo si se cumplen las restricciones definidas en la tabla.

Podemos contemplar los siguientes tipos de restricciones de integridad de datos:

• NOT NULL: especifica que la columna no puede contener un valor nulo.

• PRIMARY KEY: identifica de manera única a cada fila de la tabla mediante una o varias columas, estas columnas que forman la clave primaria no pueden tener valores nulos.

• FOREIGN KEY: establece una relación entre una(s) columna(s) de la tabla y otra(s) columna(s) de la tabla referenciada, siendo esta última(s) columna(s) la PRIMARY KEY.

• CHECK: especifica una condición que se debe evaluar a “cierto”.

De las restricciones, sólo vamos a utilizar, de momento, la clave primaria, que puede contener

tantas columnas como se necesiten:

PRIMARY KEY (columna[,columna[, ...]])

5 Todos los SGBDR permiten crear tablas sin restricciones de clave primaria, pero un correcto diseño de bases de datos incluirá claves ajenas que no se pueden definir si no existen sus correspondientes claves primarias. Las claves ajenas se introducen en la siguiente sesión.

Page 36: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

36

Por ejemplo:

create table profesores (DNI varchar2(10), nombre varchar2(40), categoria char(4), ingreso date, primary key (DNI));6

create table asignaturas (codigo char(5), descripcion varchar2(35), creditos number(3,1) creditosp number(3,1), primary key (codigo))7

resultado: 1 tabla creada 1 tabla creada

Ahora ya podemos ejecutar una consulta sobre cualquiera de estas dos tablas:

select * from profesores

resultado: ninguna fila seleccionada

El resultado de la creación es una tabla vacía, sin filas, lista para insertar datos en ellas (orden insert, a continuación). Al crear una tabla, el resultado es persistente, la tabla no “desaparece” cuando nos desconectamos del servidor (tampoco los datos que almacenamos en ella). Si queremos borrar una tabla debemos ordenárselo al SGBD mediante la orden DROP TABLE:

DROP TABLE nombreTabla

Por ejemplo:

drop table asignaturas

resultado: 1 tabla borrada

Al utilizar esta orden nótese que también se eliminan los datos (las filas) que pudiera contener. Ahora podríamos volver a crear la tabla (sin filas), con los mismos o diferentes atributos, y volver a borrarla, y...

LA ORDEN INSERT Para introducir datos nuevos en una base de datos vamos a utilizar la orden INSERT de SQL.

Con la sintaxis que se muestra a continuación seremos capaces de introducir datos nuevos en cualquiera de las tablas que componen una determinada BD. En principio, veremos la expresión mínima de la orden, formada por dos cláusulas, into y values.

INSERT INTO nombreTabla VALUES ( listaExpresiones )

Supongamos que en la base de datos anterior queremos dar de alta un nuevo profesor. Si dicho profesor tiene como dni el “55555555”, nombre “PATRICIO MARTÍNEZ”, categoría “TU” y fecha de incorporación “01/01/2000”, deberíamos ejecutar la siguiente orden.

6 Para facilitar su uso, los nombres de tabla y las columnas no deben incluir acentos o caracteres no habituales

7 El “punto y coma” es necesario para informar a Oracle de que una orden ha de ejecutarse y que, a continuación, se va a ejecutar otra orden distinta. Si sólo se escribe una orden no hace falta este caracter. No obstante, por la implementación del cliente Worksheet, se aconseja terminar todas las órdenes con punto y coma, incluso si sólo es una.

Page 37: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

37

Insert into profesores values (‘55555555’,’PATRICIO MARTINEZ’,’TU’,’01/01/2000’);

resultado: 1 fila creada

Sólo se puede indicar una tabla en la que introducir datos, no se permite una lista de nombres de tabla para introducir datos en varias tablas a la vez. Para introducir datos en n tablas, habrá que ejecutar n sentencias INSERT.

insert into profesores, asignaturas values (‘55555555’,’PATRICIO MARTINEZ’,’TU’, ’01/01/2000’, ‘BdI’,’BASES DE DATOS I’,6,0);

resultado: ERROR falta la palabra clave values

Lo mismo ocurre con las filas, sólo se puede indicar una lista de valores. Esto quiere decir que hay que ejecutar una orden insert por cada una de las filas que queramos almacenar en una tabla

insert into profesores values (‘66’,’ERNESTO PEREZ’,’ASO6’, ’10/10/2001’);

resultado: 1 fila creada

Resultado El resultado que devuelve una orden INSERT, será siempre el número de filas insertadas, en el

caso de que la ejecución haya sido correcta. Para los casos en que la ejecución de la sentencia viole alguna restricción de la BD y por tanto, su ejecución no sea correcta, el resultado indicará cuál es la restricción violada.

El SGBD, cada vez que insertamos un nuevo dato en una tabla, se encarga de verificar las restricciones activas, en nuestro caso las claves primarias, que como sabemos, no admiten valores duplicados, ni valores nulos.

insert into profesores values (‘66’,’PEPITO’,’XXX’, ’11/11/2006’);

resultado: ERROR restricción única (BDI.SYS_C0033923) 8 violada

VALUES Si no se va a dar valor a todas las columnas de la tabla se deberá indicar las columnas a las

que se les dará valor. Así, si por ejemplo, sólo supiéramos el dni y el nombre del profesor que queremos dar de alta, ejecutaríamos la sentencia siguiente

Insert into profesores (dni, nombre) values (‘88888888’, ‘ARMANDO SUAREZ’);

resultado: 1 fila creada

Es recomendable acostumbrarse a poner siempre las columnas a las que se va a dar valor, sean o no todas las de la tabla. Las razones que lo aconsejan son:

8 Nombre de la restricción.

Page 38: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

38

• No habrá que fijarse en si se va a dar valor a todas o sólo a alguna de las columnas para acomodar la sintaxis de la sentencia INSERT.

• Si por alguna razón se modifica la estructura de una tabla, es decir, se añaden columnas nuevas, y tenemos costumbre de no indicar las columnas cuando se inserta valor a todas, con la modificación dejarán de funcionar las sentencias que tuviéramos escritas.

Existe la posibilidad de hacer uso del valor NULL. Puesto que NULL es la ausencia de valor, si lo asignamos como valor a una columna de una tabla, lo que estaremos haciendo es indicar que esa columna no tiene valor. La siguiente sentencia realiza la misma operación que la anterior.

Insert into profesores (dni,nombre,categoria,ingreso) values (‘88888888’,’ARMANDO SUAREZ’, NULL, NULL);

resultado: 1 fila creada

La lista de valores se asigna a la lista de columnas, de forma que la primera columna toma el primer valor, la segunda el segundo y así sucesivamente. Es decir, las dos sentencias siguientes realizan exactamente la misma operación, aunque el orden de asignación es diferente.

Insert into profesores (dni,nombre,categoria) values (‘88888888’,’ARMANDO SUAREZ’, NULL);

resultado: 1 fila creada

Insert into profesores (categoria,dni,nombre) values (NULL, ‘88888888’,’ARMANDO SUAREZ’);

resultado: 1 fila creada

Ésto apoya aún más el hecho de que sea aconsejable poner siempre la lista de columnas, ya que aún dando valor a todas las columnas de la tabla, si no las indicamos, la lista de valores deberá seguir el orden que esas columnas tienen internamente en la tabla. Es decir, estaremos obligados a mirar las columnas y su orden, para poder establecer el orden adecuado en la lista de valores.

INFORMACIÓN SOBRE UNA TABLA Recordemos que ejecutar DESC nombreTabla o DESCRIBE nombreTabla, muestra

información sobre las columnas que componen la tabla, el orden interno de las mismas en la tabla, y sus tipos de datos.

INFORMACIÓN SOBRE LAS RESTRICCIONES DE UNA TABLA

En el momento de crear una restricción, además de especificar las reglas que se deben cumplir, podemos dar un nombre a la misma. Para establecer los nombres de las restricciones, se suele seguir el siguiente convenio: ser nombres descriptivos y empezar, por ejemplo, por PK_ si se trata de una Primary Key o por FK_ si se trata de una Foreign Key o por C_ si se trata de una CHECK.

No vamos a profundizar más en los nombres de las restricciones ni en la sintaxis para crearlos, pero sí que debemos saber que si no especificamos ningún nombre, Oracle asigna un nombre único a cada restricción con el formato SYS_Cn, siendo n un valor entero.

Page 39: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

39

La sentecia DESC sólo muestra, a nivel de restricción, si una columna determinada admite o no nulos, pero no facilita ninguna información sobre otro tipo de restricciones.

Para obtener la información relativa a otras restricciones definidas sobre una tabla se deberá ejecutar una consulta, sobre la tabla USER_CONSTRAINTS, del tipo siguiente:

select constraint_name, constraint_type, search_condition from user_constraints where table_name =’nombreTabla’ 9 ;

Donde

• Constraint_name es el nombre de la restricción. • Constraint_type puede tomar distintos valores, P indica que la restricción es de clave

primaria, R que es ajena y C una check. • Search_condition es la condición impuesta en caso de que la restricción sea de tipo

check. Si, por ejemplo, quisiéramos saber las restricciones definidas sobre la tabla IMPARTE,

ejecutaríamos la siguiente consulta

select constraint_name, constraint_type, search_condition from user_constraints where table_name =’IMPARTE’;

resultado: CONSTRAINT_NAME C SEARCH_CONDITION ------------------------------ - ----------------- SYS_C0058701 P SYS_C0058702 R SYS_C0058703 R

9 (1) nombreTabla debe indicarse en mayúsculas.

Page 40: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

40

ÓRDENES CREATE

1. Crea una tabla de nombre XX con 2 columnas, col1 de tipo integer, y col2 de tipo char(3), con col1 como clave primaria.

2. consulta la tabla

3. inserta en la tabla la fila (1,’AA’)

4. ejecuta insert into XX values (‘BB’,2)

5. insert en la tabla la fila (2,’BB’)

6. consulta la tabla XX

7. cierra la sesión de Worksheet e identifícate de nuevo (“salte y vuelve a entrar”)

8. comprueba que, efectivamente, los datos siguen estando ahí

9. borra la tabla XX

10. consulta la tabla XX

11. crea una tabla YY con 3 columnas col1(integer), col2(char(2)) y col3(varchar2(10)), cuya clave primaria sea (col1, col2)

12. inserta los siguientes datos y consulta la tabla para ver los datos almacenados

(1,’AA’,’primera’)

(2,’AA’,’segunda’)

(2,’BB’,’tercera’)

(1,’AA’,’cuarta’)

(NULL,NULL,’quinta’)

(NULL,’CC’,’sexta’)

(3,NULL,’séptima’)

(0,’’,’octava’)10

(3,’AA’,NULL)

13. crea un listín de teléfonos con los siguientes datos: apodo, nombre, teléfono; rellénala con datos (4 filas será suficiente)

14. modifica la tabla anterior, añádele una columna más, grado de amistad, y vuelve a rellenarla de datos

15. crea una lista de la compra y rellénala de datos

10 “cero”, “dos comillas simples”,”octava”

Page 41: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

41

manipulación 1

MANIPULACIÓN DE DATOS (1)

Objetivos:

• Introducir al alumno en el concepto de clave ajena, influencia de las mismas en las sentencias Insert y Delete.

Contenidos

• La orden INSERT (2). Insertar las filas resultantes de una SELECT. • La orden DELETE. Borrar todas las filas de una tabla. Borrar determinadas filas. • Creación de tablas con claves ajenas. • Influencia de las claves ajenas en la sentencia INSERT y DELETE.

Supongamos que en la BD Ejemplo existiera una tabla llamada OPTATIVAS que contuviera los

códigos y los créditos de aquellas asignaturas de carácter optativo.

Vamos a crear dicha tabla, eligiendo como clave primaria el código de la asignatura y poniendo además otra restricción, que todas las filas tengan un valor no nulo en la columna créditos

create table optativas (asignatura char (5), creditos number(3,1) not null, primary key (asignaturas))

LA ORDEN INSERT Existe la posibilidad de insertar el resultado de una SELECT, en lugar de indicar la lista concreta

de valores a insertar. Esto nos permite insertar varias filas en una tabla con una sola operación, en concreto, tantas filas como tuplas devuelva la SELECT.

INSERT INTO nombreTabla [ ( listaColumnas ) ] consulta

Supongamos que serán optativas todas las asignaturas que tengan menos de 9 créditos. Se trata de introducir los códigos de dichas asignaturas en la tabla OPTATIVAS.

En este caso, como ya tenemos las asignaturas en la tabla ASIGNATURAS, tenemos dos opciones. Una opción es, hacer la SELECT e ir haciendo las INSERT una a una, copiando los datos de las filas obtenidas. Otra opción es insertar en una sola operación el resultado de la SELECT en la tabla OPTATIVAS.

Insert into optativas (asignatura, creditos) select codigo, creditos from asignaturas where creditos < 9;

Page 42: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

42

resultado: 4 filas creadas

La SELECT deberá seleccionar tantas columnas como columnas pongamos en la lista de columnas de la parte insert y los tipos de datos de las columnas seleccionadas deberán coincidir con los tipos de datos de las columnas en las que se van a insertar esos valores.

Insert into optativas (asignatura) select codigo, creditos from asignaturas where creditos < 9;

resultado: ERROR demasiados valores

Insert into optativas (asignatura,creditos) select codigo from asignaturas where creditos < 9;

resultado: ERROR no hay suficientes valores

Insert into optativas (asignatura,creditos) select dni,ingreso from profesores;

resultado: ERROR tipos de dato inconsistentes

Insert into optativas (asignatura) select codigo from asignaturas where creditos < 4;

resultado:ERROR no se puede realizar una inserción NULL en (BDI.OPTATIVAS.CREDITOS)

En esta última sentencia la restricción NOT NULL sobre la columna creditos impide que se realice la inserción de filas, para asegurar la integridad de los datos, evitando que se pongan valores nulos en esa columna.

Por otra parte, es importante fijarse en que la sintaxis de la sentencia INSERT no permite utilizar a la vez una lista de valores y el resultado de una consulta.

Insert into imparte (dni, asignatura) values (‘55555555’,select codigo from asignaturas);

resultado: ERROR falta una expresión

Pero sí dentro de la propia orden select:

Insert into imparte (dni, asignatura) select ‘55555555’,codigo from asignaturas;

resultado: 4 filas creadas

LA ORDEN DELETE La sentencia DELETE nos permite borrar las filas contenidas en una tabla.

DELETE [FROM] nombreTabla [WHERE condición]

No se pueden borrar filas de varias tablas a la vez en una misma sentencia. Para borrar filas de varias tablas habrá que ejecutar tantas sentencias DELETE como de tablas queramos borrar.

Delete from asignaturas a, imparte i where a.codigo = i.asignatura and i.dni=’21111222’; resultado: ERROR comando SQL no terminado correctamente

Page 43: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

43

CLÁUSULA WHERE

Si no se especifica ninguna condición, la sentencia causará el borrado de todas las filas de la tabla.

Delete from asignaturas; resultado: 5 filas suprimidas

En el caso de que se indique alguna condición, se borrarán sólo aquellas filas de la tabla que cumplan la condición o condiciones impuestas. Así, la siguiente sentencia, a diferencia de la anterior que borra todas las filas de la tabla asignaturas, hará que se borren sólo las asignaturas que tengan menos de 5 créditos.

Delete from asignaturas where creditos < 5;

resultado: 1 fila suprimida

La condición indicada en la cláusula where puede ser tan complicada como se desee. Por ejemplo, la sentencia siguiente borra aquellas asignaturas que son impartidas por profesores con categoría de TEU.

Delete from asignaturas where codigo in (select asignatura from imparte i, profesores p where i.dni = p.dni and p.categoria=’TEU’);

Resultado: 1 fila suprimida

CREACIÓN DE TABLAS CON CLAVES AJENAS Relacionemos ahora las tablas PROFESORES y ASIGNATURAS mediante la tabla IMPARTE, de

forma que para cada profesor que tenga docencia, se indique en la tabla IMPARTE su dni junto con el código de la asignatura que imparta. Cada profesor tendrá tantas filas, en esta nueva tabla, como asignaturas imparta.

IMPARTE ( dni : varchar2(10), asignatura : char(5) ) Clave primaria: (dni, asignatura) Clave ajena: dni → PROFESORES Clave ajena: asignatura → ASIGNATURAS

Evidentemente, se deberá exigir que el valor que tenga la columna dni exista en la tabla PROFESORES, de la misma manera cada código de asignatura deberá existir en la tabla ASIGNATURAS, esto es lo que se conoce como integridad referencial y se consigue mediante las denominadas claves ajenas:.

columna REFERENCES tabla

La sentencia de creación de esta tabla, junto con sus restricciones de clave primaria y claves ajenas es

create table imparte ( dni varchar2(10) references profesores, asignatura char(5) references asignaturas, primary key (dni,asignatura ) );

Con esta sintaxis a nivel de columna, cada clave ajena sólo puede estar formada por una sola columna.

Page 44: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

44

Veamos otra sintaxis para definir claves ajenas, mediante las palabras reservadas FOREIGN KEY, que nos permite designar varias columnas como clave ajena.

FOREIGN KEY (columna[,columna[, ...]]) REFERENCES tabla

Con esta sintaxis, vamos a escribir una sentencia equivalente a la anterior

create table imparte ( dni varchar2(10), asignatura char(5), primary key (dni,asignatura ), foreign key (dni) references profesores (dni), foreign key (asignatura) references asignaturas (codigo) );

Sea cual sea la sintaxis elegida para su definición, las columnas que conforman la clave ajena han de coincidir en número (y orden) y tipo de datos con la clave primaria de la tabla a la que se va a hacer referencia.

Una restricción de integridad referencial designa una columna o combinación de columnas como clave ajena de una tabla (la tabla hija) y establece una relación entre ella y la clave primaria de otra tabla (la tabla padre11). Por ejemplo, en la última línea de la sentencia, la clave ajena asignatura hace referencia a la clave primaria codigo de la tabla padre asignaturas.

Toda clave ajena, si no tiene un valor nulo, debe tener un valor que coincida con un valor existente en la tabla padre.

CLAVES AJENAS: influencia en el INSERT En una tabla con claves ajenas, sólo se podrán insertar aquellas filas cuyas claves ajenas

existan en la correspondiente tabla padre.

En el siguiente ejemplo la inserción no es posible pues no existe la asignatura ‘AAA’.

insert into imparte (dni, asignatura) values ('55555555','AAA'); resultado: ERROR restricción de integridad (BDI.SYS_C0058700) violada - clave principal

no encontrada

insert into imparte (dni, asignatura) values ('21333444','FP'); resultado: 1 fila creada

CLAVES AJENAS: influencia en el DELETE

Sólo se podrán borrar aquellas filas que no estén siendo referenciadas, a través de ninguna clave ajena, desde otra tabla. Si por ejemplo tenemos que la asignatura BDA es impartida por el profesor con dni 21111222, no se podrá borrar la asignatura si antes no se eliminan las líneas correspondientes a esa asignatura en la tabla imparte.

Delete from asignaturas where codigo = ‘FBD’; resultado: ERROR:restricción de integridad (BDI.SYS_C0058700) violada - registro

secundario encontrado

11 La tabla padre puede ser la misma tabla hija

Page 45: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

45

Para poder realizar esta operación, será necesario primero eliminar las filas de imparte que hagan referencia a esa asignatura. Una vez que la asignatura ya no está siendo referenciada desde ninguna otra tabla, puede ser eliminada.

Delete from imparte where asignatura = ‘FBD’; resultado: 1 fila suprimida

Delete from asignaturas where codigo = ‘FBD’; Resultado: 1 fila suprimida

EJERCICIOS MANIPULACIÓN1 Si alguna de las sentencias no se puede realizar, explica el motivo del error

1. Partiendo del ejercicio 13 de la sesión anterior, deberemos tener la sentencia de creación de la tabla LISTIN, con las siguientes columnas: apodo, nombre, telefono, grado. Como clave primaria podemos elegir apodo. También tendremos las sentencias insert para incorporar algunas filas. Ejecutemos todo ello para tener la tabla LISTIN con algunas filas.

2. Crear la tabla AMISTAD con las columnas grado y descripcion , para reflejar los diferentes grados de amistad y su descripción: amigo, colega, etc. Por lo pronto vamos a crear sólo la tabla. Sin incorporar datos.

3. Borremos la tabla LISTIN. Y volvamos a crearla, pero añadiendo una restricción: que la columna grado sea clave ajena que referencie a AMISTAD.

4. Ejecutemos las sentencias del punto 1 para insertar algunas filas en LISTIN.

5. Mirando detenidamente las anteriores sentencias hagamos SÓLO los insert NECESARIOS en la tabla AMISTAD.

6. Volvamos a ejecutar las sentencias del punto 4.

7. Crear un nuevo grado de amistad en AMISTAD.

8. Borremos TODAS las filas de AMISTAD. Mira las filas de AMISTAD y explica que sucede.

9. Borremos ahora sólo una fila, la última que hemos añadido.

10. Borremos de AMISTAD la fila que más referencias tenga, hagamos una select de LISTIN y contemos visualmente.

11. Borremos las filas necesarias del LISTIN que nos permitan ejecutar el punto 10.

12. Volvamos a ejecutar el punto 10.

Page 46: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

46

Page 47: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

47

manipulación 2

MANIPULACIÓN DE DATOS (2)

Objetivos:

• Introducir al alumno en la orden UPDATE. • Practicar con la integridad referencial.

Contenidos

• Actualizar los valores existentes en tablas de la base de datos. • Actualizar los valores existentes en tablas de la base de datos a través de subconsultas.

LA ORDEN UPDATE La sentencia UPDATE nos permite modificar la información contenida en una tabla.

UPDATE nombreTabla [aliasTabla] SET columna=expresion [WHERE condición]

No se pueden modificar varias tablas a la vez en una misma sentencia. Para modificar los valores de varias tablas varias habrá que ejecutar tantas sentencias UPDATE como de tablas queramos modificar.

Update asignaturas a, imparte i set creditos= 2 where a.codigo = i.asignatura and i.dni=’21111222’;

resultado: ERROR falta la palabra clave SET

CLÁUSULA SET En la cláusula SET se especifican las columnas de la tabla cuyos valores se desean modificar y

los nuevos valores que se van a asignar a dichas columnas. Por ejemplo, la siguiente sentencia hace que la columna créditos de la tabla asignaturas pase a tener valor 0.

Update asignaturas set creditos = 0; resultado: 4 filas actualizadas

Cuando se desea modificar más de una columna se indicará la lista de columnas y valores separadas por comas. En el ejemplo que se muestra a continuación, a la columna créditos se le asigna el valor 4 y a la columna créditosp el valor 2.

Update asignaturas set creditos=4, creditosp=2; Resultado: 4 filas modificadas

Debe existir concordancia entre los tipos de datos de las columnas y el de los valores asignados a las mismas.

Page 48: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

48

Update asignaturas set creditos=’01/01/2002’, creditosp=2; Resultado: ERROR número no válido

CLÁUSULA WHERE

Si no se especifica ninguna condición, la sentencia causará la modificación de todas las filas de la tabla.

Update profesores set ingreso=’01/01/2003’; resultado: 3 filas modificadas

En el caso de que se indique alguna condición, se modificarán sólo aquellas filas de la tabla que cumplan la condición o condiciones impuestas. Así, la siguiente sentencia, a diferencia de la anterior que modifica todas las filas de la tabla profesores, hará que se modifique la fecha de ingreso sólo a aquellos profesores cuya categoría sea TEU.

Update profesores set ingreso=’01/01/2003’ where categoria = ‘TEU’; resultado: 2 filas modificadas

La condición indicada en la cláusula where puede ser tan complicada como se desee. Por ejemplo, la sentencia siguiente modifica los créditos de las asignaturas que son impartidas por profesores con categoría de TEU.

Update asignaturas set creditos = 0 where codigo in (select asignatura from imparte i, profesores p where i.dni = p.dni and p.categoria=’TEU’);

Resultado: 1 fila modificada

MODIFICACIÓN DE MÁS DE UNA FILA Existe la posibilidad de modificar la información contenida en una tabla asignando como nuevo

valor o valores, el resultado de una consulta.

UPDATE nombreTabla [aliasTabla] SET { {columna=expresion|columna=subconsulta} |

listaColumnas=subconsulta} [WHERE condición]

El resultado de la consulta puede asignarse a una única columna o a una lista de columnas. En el primer caso, la sentencia SELECT sólo devolverá un valor (una fila y una columna) el cual debe coincidir en tipo de dato y longitud con el tipo de dato y longitud de la columna a la cual asignamos el valor.

Update imparte set asignatura=’BDA’, dni = (select dni from profesores where categoria=’ASO6’)

where asignatura like ‘%BD%’; resultado: 1 fila actualizada

Si la restricción de que la consulta devuelva una fila y una columna no se cumple no se realiza la actulización.

Update imparte set asignatura=’BDA’,

Page 49: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

49

dni = (select dni from profesores) where asignatura like ‘%BD%’;

resultado: ERROR la subconsulta devuelve más de una fila

Update imparte set asignatura=’BDA’, dni = (select dni, nombre from profesores where categoria =’ASO6’)

where asignatura like ‘%BD%’; resultado: ERROR demasiados valores

La segunda opción asigna el resultado de una consulta a una lista de columnas. En este caso, la sentencia SELECT devolverá una única fila, pero con tantas columnas como elementos haya en la lista de columnas. Los valores se asignan por orden, de forma que a la primera columna se le asigna el valor de la primera columna de la SELECT, a la segunda la segunda, y así sucesivamente. En el ejemplo siguiente se seleccionan dos columnas para dar valor a las columnas dni y asignatura de la tabla impartir.

Update imparte set (dni,asignatura) = (select dni, ‘BDA’ from profesores where categoria =’ASO6’)

where asignatura like ‘%BD%’; resultado: 1 fila actualizada

Update imparte set (dni,asignatura) = (select dni, ‘BDA’ from profesores)

where asignatura like ‘%BD%’; resultado: ERROR la subconsulta devuelve más de una fila

Update imparte set (dni,asignatura) = (select dni, ‘BDA’, nombre from profesores where categoria =’ASO6’)

where asignatura like ‘%BD%’; resultado: ERROR demasiados valores

Update imparte set (dni,asignatura) = (select dni from profesores where categoria =’ASO6’)

where asignatura like ‘%BD%’; resultado: ERROR no hay suficientes valores

Deberá existir una concordancia de tipo de dato y longitud entre los elementos de la lista de columnas y las columnas seleccionadas.

CLAVES AJENAS: influencia en el UPDATE

En general, las claves ajenas generan las mismas restricciones de integridad referencial que el DELETE salvo por la naturaleza de la operación: el UPDATE sólo generará problemas de integridad referencial si el dato a modificar es un valor de clave primaria que está siendo referenciada por alguna clave ajena. Suponiendo el estado de la base de datos original:

Update asignaturas set codigo = BD1 where codigo = ‘FBD’;

Page 50: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

50

resultado: ERROR:restricción de integridad (BDI.SYS_C005870012) violada - registro secundario encontrado

Para poder realizar esta operación, será necesario insertar una nueva fila en asignaturas con el identificador BD1 y copiando el resto de los valores, después cambiar las referencias a ‘FBD’ por ‘BD1’ y, por último, borrar la fila de ‘FBD’.

Insert into asignaturas (codigo,descripcion,creditos,creditosp) select ‘BD1’, descripcion,creditos,creditosp from asignaturas where codigo = ‘FBD’;

resultado: 1 fila insertada

Update imparte set asignatura = ‘BD1’ where asignatura = ‘FBD’; Resultado: 1 fila suprimida

Delete from asignaturas where codigo = ‘FBD’; Resultado: 1 fila suprimida

ÓRDENES MANIPULACIÓN2 Los siguientes ejercicios se ejecutarán sobre la base de datos de Proveedores, ya conocida. Antes de comenzar, deberás ejecutar las instrucciones contenidas en el fichero BD1CreateBD.sql para la creación de la BD e inserción de datos iniciales.

1. Haz que la fecha de recuento del inventario de todas las piezas sea el 1 de enero de 2003.

2. Modifica la cantidad mínima de todas las piezas inventariadas que cumplan que la cantidad disponible es menor. Haz que tomen el valor de la cantidad disponible de cada una de ellas.

3. Para aquellos vendedores para los que no tengamos teléfono, ponles el valor ‘SIN TLFNO’.

4. Haz que la calle, la ciudad y la provincia de los vendedores de TOLEDO sea ‘CENTRAL, 5’,‘SALAMANCA’, ‘SALAMANCA’.

5. Modifica los datos de las piezas que no tengan descripción. Haz que tomen el valor ‘SIN DESCRIPCION’.

6. Las piezas suministradas por el vendedor de número 3 van a ser suministradas a partir de ahora por el de número 500, a un preciounitario de 5 euros.

7. Pon a 0 el descuento de las piezas cuyos días de suministro sea inferior a 3.

8. Para pedidos anteriores al año 2000, modifica el número de vendedor por el 3.

9. Modifica los pedidos realizados por el vendedor de número 200 de forma que los haya realizado el vendedor de número 1000.

10. El pedido con número 8 va a tener a partir de ahora el número 4, el pedido con número 5 va a tener a partir de ahora el pedido con número 1, el 8 será el 2 a partir de ahora y el 3 el 2.

12 Recuérdese que el identificador de restricción (en este caso, una clave ajena) lo asigna el sistema y puede cambiar de un usuario a otro.

Page 51: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

51

11. Para los pedidos en los que la cantidad recibida variara de la pedida, haz que no sea así.

12. Actualiza la ciudad y la provincia de los vendedores que no sean de ALICANTE. Asígnales los valores de la ciudad y la provincia del vendedor de número 3.

13. Modifica la descripción de las piezas que estén SIN DESCRIPCIÓN asignándoles la descripción de la que tenga el precio de venta igual a 7 euros.

14. Actualiza el precio de venta de la pieza de número A-1001-L a 4 euros y el de la pieza de número C-1002-H a 15.

15. A partir de ahora el vendedor número 5 suministrará la pieza DISKETTE 1.44 PANASONIC al precio de venta de la misma.

16. Haz lo mismo que en el ejercicio anterior, pero para el vendedor de número 200.

17. Los pedidos del vendedor número 3 han sido realizados a fecha de hoy.

18. Pon el precio de compra igual al precio de venta, la cantidad pedida y recibida a 100 y la fecha de recepción a la fecha del día, para las líneas de pedido en las que la pieza pedida sea A-1001-L.

19. Modifica los datos de las piezas recontadas con anterioridad al 1 de enero de 2003 de forma que el período de recuento sea el mismo que para las piezas recontadas

Page 52: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

52

Page 53: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

53

manipulación 3

INTEGRIDAD REFERENCIAL Y

BORRADOS Objetivos:

• Extender la gestión de las claves ajenas y automatizar el borrado cuando produce problemas de integridad referencial.

Contenidos

• Cláusula ON DELETE (políticas de mantenimiento de la integridad referencial en las claves ajenas ante borrados en claves primarias)

ON DELETE Ya se ha practicado con la integridad referencial en sesiones anteriores y se ha visto que el

intento de borrar ciertas filas es rechazado por el SGBD si éstas están siendo referenciadas por alguna clave ajena. Recordemos la estructura y el contenido de la base de datos Ejemplo:

PROFESORES ( dni : char(9), nombre : char(25), categoria : char(4), ingreso : date ) Clave primaria: dni

ASIGNATURAS ( codigo : char(5), descripcion : char(40), creditos : decimal(3,1), creditosp : decimal(3,1) ) Clave primaria: codigo

IMPARTE ( dni : char(9), asignatura : char(5) ) Clave primaria: (dni, asignatura) Clave ajena: dni → PROFESORES Clave ajena: asignatura → ASIGNATURAS

Extensiones de Ejemplo:

ASIGNATURAS

codigo descripcion creditos creditosp HI HISTORIA DE LA INFORMATICA 4.5 FBD FUNDAMENTOS DE LAS BASES DE DATOS 6.0 1.5 DGBD DISEÑO Y GESTION DE BASES DE DATOS 6.0 3.0 PC PROGRAMACION CONCURRENTE 6.0 1.5 FP FUNDAMENTOS DE LA PROGRAMACION 9.0 4.5

Page 54: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

54

PROFESORES IMPARTE

dni nombre categoria ingreso dni asignatura 21111222 EVA GOMEZ TEU 01/10/1993 21111222 FBD 21222333 MANUEL PALOMAR TEU 16/06/1989 21111222 DGBD 21333444 RAFAEL ROMERO ASO6 16/06/1992 21333444 PC

No hay ningún problema en borrar cualquier fila de la tabla IMPARTE, no existen claves ajenas

que les hagan referencia, pero tanto PROFESORES como ASIGNATURAS son referenciadas por las claves ajenas definidas en IMPARTE y según el estado de la BD ciertas filas pueden ser eliminadas y otras no. Por ejemplo, podemos eliminar “Historia de la Informática” puesto que ningún profesor la imparte, pero si intentamos eliminar “Fundamentos de las Bases de Datos” el sistema mostrará un error y no realizará la operación.

Delete from asignaturas where codigo = ‘FBD’; resultado: ERROR:restricción de integridad (BDI.SYS_C0058700) violada - registro

secundario encontrado

En ciertos sistemas de información es posible redefinir las restricciones de clave ajena para que no se den estos mensajes de error. Ello es posible mediante la cláusula ON DELETE al crear una tabla:

FOREIGN KEY (columna[,columna[, ...]]) REFERENCES tabla ON DELETE {CASCADE | SET NULL}

La acción a realizar ante el borrado de una fila que está siendo referenciada por alguna clave ajena puede ser el propagar la operacion (ON DELETE CASCADE) o anular (ON DELETE SET NULL), dependiendo de la decisión del diseñador de la base de datos.

PROPAGAR EL BORRADO Supongamos que la tabla IMPARTE de la BD Ejemplo tiene la siguiente definición:

create table IMPARTE ( dni varchar2(10), asignatura char(5), primary key (dni, asignatura), foreign key (dni) references PROFESORES (dni), foreign key (asignatura) references ASIGNATURAS (codigo)

ON DELETE CASCADE);

El resultado del borrado anteriormente intentado sería ahora:

Delete from asignaturas where codigo = ‘FBD’; resultado: 1 fila suprimida

Page 55: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

55

ASIGNATURAS

codigo descripcion creditos creditosp HI HISTORIA DE LA INFORMATICA 4.5 DGBD DISEÑO Y GESTION DE BASES DE DATOS 6.0 3.0 PC PROGRAMACION CONCURRENTE 6.0 1.5 FP FUNDAMENTOS DE LA PROGRAMACION 9.0 4.5

PROFESORES IMPARTE

dni nombre categoria ingreso dni asignatura 21111222 EVA GOMEZ TEU 01/10/1993 21111222 DGBD 21222333 MANUEL PALOMAR TEU 16/06/1989 21333444 PC 21333444 RAFAEL ROMERO ASO6 16/06/1992

Como ya hemos dicho, eliminar la asignatura Historia de la Informática no genera conflictos de integridad referencial por lo que el sistema puede hacerlo sin problemas:

Delete from asignaturas where codigo = ‘HI’; resultado: 1 fila suprimida

ASIGNATURAS

codigo descripcion creditos creditosp DGBD DISEÑO Y GESTION DE BASES DE DATOS 6.0 3.0 PC PROGRAMACION CONCURRENTE 6.0 1.5 FP FUNDAMENTOS DE LA PROGRAMACION 9.0 4.5

PROFESORES IMPARTE

dni nombre categoria ingreso dni asignatura 21111222 EVA GOMEZ TEU 01/10/1993 21111222 DGBD 21222333 MANUEL PALOMAR TEU 16/06/1989 21333444 PC 21333444 RAFAEL ROMERO ASO6 16/06/1992

Sin embargo, nótese que la clave ajena dni que hace referencia a PROFESORES no tiene modificado su comportamiento ante borrados:

Delete from profesores where dni = ‘21111222’; resultado: ERROR:restricción de integridad (BDI.SYS_xxxxx) violada - registro

secundario encontrado

Delete from profesores where dni = ‘21222333’; resultado: 1 fila borrada

La fila de Eva GOMEZ no ha podido ser eliminada puesto que imparte DGBD (y no se ha modificado con ON DELETE) pero sí se ha borrado la de Manuel Palomar, que no imparte asignatura alguna.

Page 56: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

56

ASIGNATURAS

codigo descripcion creditos creditospDGBD DISEÑO Y GESTION DE BASES DE DATOS 6.0 3.0 PC PROGRAMACION CONCURRENTE 6.0 1.5 FP FUNDAMENTOS DE LA PROGRAMACION 9.0 4.5

PROFESORES IMPARTE

dni nombre categoria ingreso dni asignatura 21111222 EVA GOMEZ TEU 01/10/1993 21111222 DGBD 21222333 MANUEL PALOMAR TEU 16/06/1989 21333444 PC

ANULAR EL VALOR DE CLAVE AJENA Si la modificación de una clave ajena es ON DELETE SET NULL, la acción que llevará a cabo

automáticamente el SGBD es la de poner NULOS en aquellos casos en que la integridad referencial se vea comprometida. Esta definición tiene más dificultad de aplicación puesto que prevalecen las definiciones de clave candidata. Por ejemplo, la siguiente definición es inútil puesto que dni en IMPARTE forma parte de la clave primaria y no admite nulos en ningún caso:

create table IMPARTE ( dni varchar2(10), asignatura char(5), primary key (dni, asignatura), foreign key (dni) references PROFESORES (dni) ON DELETE SET NULL, foreign key (asignatura) references ASIGNATURAS (codigo) );

Delete from profesores where dni = ‘21111222’; resultado: ERROR: no se puede actualizar (“IMPARTE”.”DNI”) a un valor NULL

El sistema ha intentado cambiar el valor ‘21111222’ en la tabla IMPARTE por un nulo pero, al ser parte de la clave primaria, ha rechazado la operación.

Supongamos que la tabla imparte tiene esta otra definición:

create table IMPARTE ( ficha integer, dni varchar2(10), asignatura char(5), primary key (ficha), foreign key (dni) references PROFESORES (dni) ON DELETE SET NULL, foreign key (asignatura) references ASIGNATURAS (codigo) );

Y el contenido de la BD es ahora:

ASIGNATURAS

codigo descripcion creditos creditospHI HISTORIA DE LA INFORMATICA 4.5 FBD FUNDAMENTOS DE LAS BASES DE DATOS 6.0 1.5 DGBD DISEÑO Y GESTION DE BASES DE DATOS 6.0 3.0 PC PROGRAMACION CONCURRENTE 6.0 1.5 FP FUNDAMENTOS DE LA PROGRAMACION 9.0 4.5

Page 57: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

57

PROFESORES

dni nombre categoria ingreso 21111222 EVA GOMEZ TEU 01/10/1993 21222333 MANUEL PALOMAR TEU 16/06/1989 21333444 RAFAEL ROMERO ASO6 16/06/1992

IMPARTE

ficha dni asignatura 1 21111222 FBD 2 21111222 DGBD 3 21333444 PC

Delete from profesores where dni = ‘21111222’; resultado: 1 fila borrada

El sistema puede borrar la fila de la profesora Eva GOMEZ, poniendo nulos en cualquier referencia que halle en la clave ajena afectada de IMPARTE.

PROFESORES

dni nombre categoria ingreso 21222333 MANUEL PALOMAR TEU 16/06/1989 21333444 RAFAEL ROMERO ASO6 16/06/1992

IMPARTE

ficha dni asignatura 1 FBD 2 DGBD 3 21333444 PC

ON UPDATE ... En Oracle9 no existe la posibilidad de establecer políticas para el mantenimiento de la

integridad referencial ante modificaciones (UPDATE) de valores de clave primaria.

Page 58: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

58

ÓRDENES MANIPULACIÓN3 Los siguientes ejercicios se ejecutarán sobre la base de datos de Proveedores, ya conocida. Antes de comenzar, deberás ejecutar las instrucciones contenidas en el fichero BD1CreateBD2.sql para la creación de la BD e inserción de datos iniciales. Nótese que se han efectuado cambios en la definición de ciertas claves ajenas para incorporar las políticas de mantenimiento de la integridad referencial ante borrados:

PRECIOSUM Clave Primaria: (numpieza, numvend) Clave Ajena: (numpieza)→ PIEZA RECHAZAR13 Clave Ajena: (numvend)→ VENDEDOR PROPAGAR

PEDIDO Clave Primaria: (numpedido) Clave Ajena: (numvend)→ VENDEDOR PROPAGAR

LINPED Clave Primaria: (numpedido, numlinea) Clave Ajena: (numpedido)→ PEDIDO PROPAGAR Clave Ajena: (numpieza)→ PIEZA ANULAR

INVENTARIO Clave Primaria: (numbin) Clave Alternativa: (numpieza) Clave Ajena: (numpieza)→ PIEZA ANULAR

Para la comprobación de los efectos de las siguientes órdenes es conveniente tener a mano la sesión Select 1 donde se muestra el contenido original de la BD PROVEEDORES.

1. Borra el vendedor 1.

2. Comprueba los efectos de la operación anterior consultando todas las tablas. 3. Borra el vendedor 3. 4. Comprueba los efectos de la operación anterior consultando todas las tablas. 5. Borra el vendedor 8001. 6. Comprueba los efectos de la operación anterior consultando todas las tablas. 7. Borra el pedido 6 8. Comprueba los efectos de la operación anterior consultando todas las tablas. 9. Borra la pieza O-0001-PP. 10. Borra todos los suministros de la pieza O-0001-PP. 11. Borra la pieza O-0001-PP. 12. Comprueba los efectos de la operación anterior consultando todas las tablas. 13. Borra todos los suministros de la pieza DD-0001-210. 14. Borra la pieza DD-0001-210. 15. Modifica BD1CreateBD2.sql (y ejecútalo después de realizada la modificación) cambiando

la política de la clave ajena de INVENTARIO a PROPAGAR, y añádele una nueva tabla con los siguientes datos: NUEVA(orden entero) CP(orden) Card(NUEVA, rel1) = (0,1) Card(PRECIOSUM, rel1) = (0,N) RECHAZAR

16. Inserta en NUEVA los 3 suministros de la pieza T-0001-IBM. 17. Intenta borrar el vendedor 2 y localiza el error producido.

18. Modifica la política de la clave ajena de NUEVA a ANULAR (y ejecuta), vuelve a insertar los suministros del ejercicio 16, y vuelve a borrar el vendedor 2, comprobando los efectos sobre la BD.

13 “Ante borrados en PIEZA, rechazar la operación si existen referencias”, y así con todas las claves ajenas definidas.

Page 59: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

59

conjuntos

OPERACIONES DE CONJUNTOS

Objetivos:

• Combinar el resultado de varias sentencias select en un único resultado, utilizando los operadores de conjuntos: unión, intersección y diferencia.

Contenidos

• Union, Union All • Intersect • Minus • Resolución de requerimientos.

OPERADORES SOBRE CONJUNTOS Un operador sobre conjuntos combina el resultado de dos sentencias SELECT en un único

resultado. Para que se pueda realizar, las sentencias SELECT deben tener ambas como resultado el mismo número de columnas y los mismos tipos de datos (no es necesario que sean de igual longitud).

Los operadores de conjuntos son la UNION, UNION ALL, INTERSECT y MINUS. En la versión de Oracle con la que trabajamos, todos tienen la misma precedencia y se evalúan de izquierda a derecha. Si queremos alterar este orden debemos utilizar los paréntesis.

UNION, UNION ALL Al utilizar el operador UNION entre dos sentencias SELECT, el resultado final estará compuesto

por todas aquellas filas que aparecen en el resultado de como mínimo una de las SELECT. El operador UNION elimina filas duplicadas en el resultado final. El operador UNION ALL opera de igual modo que el operador UNION, pero no elimina filas duplicadas en el resultado final.

Supongamos que queremos saber el nombre de los profesores que son ASO6 o imparten asignaturas de 6 créditos.

Se calcula cada SELECT por separado.

select nombre from profesores where categoria=’ASO6’

resultado: nombre RAFAEL ROMERO

Page 60: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

60

select nombre from profesores p, imparte i, asignaturas

where p.dni=i.dni and asignatura=codigo and creditos=6

resultado: nombre RAFAEL ROMERO EVA GOMEZ EVA GOMEZ

En el resultado final aparecerán todas las filas que estén en cualquiera de los dos resultados.

select nombre from profesores where categoria=’ASO6’ UNION select nombre from profesores p, imparte i, asignaturas

where p.dni=i.dni and asignatura=codigo and creditos=6

resultado con UNION ALL: nombre con UNION nombre RAFAEL ROMERO RAFAEL ROMERO RAFAEL ROMERO EVA GOMEZ EVA GOMEZ EVA GOMEZ

INTERSECT Al utilizar el operador INTERSECT entre dos sentencias SELECT, el resultado final estará

compuesto por todas aquellas filas que aparezcan en los resultados de ambas sentencias (no es suficiente que aparezcan sólo en el resultado de una de ellas)

Supongamos que queremos saber el nombre de los profesores que son ASO6 e imparten asignaturas de 6 créditos.

select nombre from profesores where categoria=’ASO6’ INTERSECT select nombre from profesores p, imparte i, asignaturas

where p.dni=i.dni and asignatura=codigo and creditos=6

resultado: nombre

RAFAEL ROMERO

Se calcula cada SELECT por separado y aparecen en el resultado final todas las filas que estén

en ambos resultados.

MINUS Al utilizar el operador MINUS entre dos sentencias SELECT, el resultado final estará compuesto

sólo por aquellas filas que aparecen en el resultado de la primera SELECT y no aparecen en el resultado de la segunda.

Supongamos que queremos saber el nombre de los profesores que son ASO6 y no imparten asignaturas de 6 créditos.

Page 61: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

61

select nombre from profesores where categoria=’ASO6’ MINUS select nombre from profesores p, imparte i, asignaturas

where p.dni=i.dni and asignatura=codigo and creditos=6

resultado: nombre

Supongamos que las condiciones hubiesen estado al revés. Queremos saber el nombre de los profesores que imparten asignaturas de 6 créditos y no son ASO6.

select nombre from profesores p, imparte i, asignaturas

where p.dni=i.dni and asignatura=codigo and creditos=6 MINUS select nombre from profesores where categoria=’ASO6’

resultado: nombre EVA GOMEZ

Algunos de estos requerimientos se pueden resolver con una sola sentencia SELECT donde se combinen de modo adecuado las condiciones. En otras ocasiones debemos recurrir a operar con los resultados de varias sentencias. Por ejemplo, en estos dos últimos enunciados, el segundo se puede solucionar con una SELECT, mientras que en el caso del primero es necesario trabajar con dos.

CONSULTAS CONJUNTOS

1. Nombre de las empresas que tienen vendedores con pedidos O que puedan suministrar la pieza ‘A-1001-L’.

2. Nombre de las empresas que tienen vendedores con pedidos Y que puedan suministrar la pieza ‘A-1001-L’.

3. Nombre de las empresas que tienen vendedores con pedidos PERO NO suministran la pieza ‘A-1001-L’.

4. Número de los pedidos en los que se soliciten teclados pero no monitores.

5. Número y nombre de las piezas que suministra el vendedor número 1, pero no el vendedor número 2.

6. Número y nombre de las piezas con un precio de venta mayor que 1000, y todas las que pueden ser suministradas por el vendedor número 1, ordenado por nombre.

7. Número y nombre de las piezas que han sido pedidas pero no inventariadas

8. Número y nombre de los vendedores de la empresa MECEMSA que, además, tienen suministros de precio unitario mayor que 10 o se les ha hecho algún pedido

Page 62: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

62

Page 63: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

63

funciones

ARITMÉTICA Y FUNCIONES

AGREGADAS Objetivos:

• Obtención de información calculada.

Contenidos

• operaciones aritméticas: +, -, *, / • SUM(), AVG(), COUNT(), MAX(), MIN(), ROUND(), ABS(). • etiquetas para columnas • Resolución de requerimientos.

Introducción de las funciones estadísticas aplicables a columnas enteras y de cuenta de filas, así como la forma de realizar operaciones como suma, producto, etc., de valores escalares.

OPERACIONES ARITMÉTICAS Se pueden utilizar expresiones aritméticas tanto en la cláusula select, para obtener una nueva

columna en la tabla resultado, como en la construcción de condiciones de selección de filas.

Número de horas semanales, en un sólo semestre, que se imparten de cada asignatura:

select descripcion, (creditos/3)*2 from asignaturas

resultado: descripcion (creditos/3)*2 Historia de la Informática 3 Fundamentos de las Bases de Datos 4 Diseño y Gestión de Bases de Datos 4 Programación Concurrente 4 Fundamentos de Programación 6

Page 64: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

64

Descripción de las asignaturas y número de horas semanales de las asignaturas con menos de 4 horas semanales de clase:

select descripcion, creditos from asignaturas where (creditos/3)*2 < 4

resultado: descripcion creditos Historia de la Informática 4.5

FUNCIONES AGREGADAS Se dispone de una serie de funciones agregadas que retornan valores calculados sobre una

determinada columna. Estas funciones devuelven un único valor para todas las tuplas seleccionadas mediante la condición de la cláusula where; si no se especifica ésta, el cálculo se realiza sobre la totalidad de la columna.

COUNT( * ) número de filas COUNT( DISTINCT expr ) número de valores distintos en la columna expr SUM( [DISTINCT] expr ) suma de todos los valores en expr AVG( [DISTINCT] expr ) promedio de todos los valores en expr

MIN( expr ) el más pequeño de todos los valores en expr MAX( expr ) el mayor de todos los valores en expr

ROUND( expr ) redondea expr ABS( expr ) valor absoluto de expr

Las funciones de tipo estadístico precisan que la expresión que se evalúe se construya sobre columnas de tipo de datos numérico.

La expresión expr puede contener el nombre de una columna o un cálculo sobre una o varias columnas.

Si se especifica la palabra clave distinct la expresión obligatoriamente ha de ser un nombre de columna, y se asume que la función se calcula únicamente sobre valores distintos de la expresión.

En ningún caso se pueden anidar funciones: avg ( min ( creditos ) ) no está permitido.

¿Cuántos profesores hay en nuestra BD?

select count( * ) from profesores

resultado: ( count( * ) ) 3

¿Cuántas asignaturas de más de 5 créditos hay en nuestra BD?

select count( * ) from asignaturas where creditos > 5

resultado: ( count( * ) ) 4

¿Cuántas valores de créditos distintos hay en nuestra BD?

select count( distinct creditos ) from asignaturas

resultado: ( count )

3

Page 65: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

65

¿Cuál es la media de créditos por asignatura?

select avg( creditos ) from asignaturas

resultado: ( avg )

6.3

¿Cuál es la media de horas por asignatura?

select avg( creditos*2/3 ) from asignaturas

resultado: ( avg ) 4.2

Total de créditos ofertados en asignaturas de Bases de Datos:

select sum( creditos ) from asignaturas where codigo like '%BD'

resultado: sum( creditos ) 12

ETIQUETAS PARA COLUMNAS Dado que las expresiones calculadas no tienen un nombre específico de columna en la salida

por pantalla, es conveniente "renombrarlas" para aclarar su significado.

Se pueden etiquetar las columnas de la tabla resultado añadiendo, antes de la coma si hubiera más columnas detrás, una cadena de no más de 18 caracteres y sin espacios en blanco, tal como se hace con los alias temporales de las tablas. Esta cadena de caracteres aparecerá en el encabezado de la columna.

select count( * ) num_asignaturas, avg(creditos) mediactos from asignaturas

resultado: num_asignaturas mediactos 5 6.30

Page 66: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

66

CONSULTAS FUNCIONES

1. Obtener la diferencia entre cantidad pedida y cantidad recibida de las líneas del pedido 1.

2. Media de días de intervalo entre la fecha de envío del pedido 1 y de entrega de las distintas piezas solicitadas en ese pedido

3. Obtener la cantidad de provincias distintas de las que tenemos conocimiento de algún proveedor.

4. Mínima diferencia entre precio de compra y precio de suministro del vendedor al que se le compró.

5. Media de precios distintos de venta de piezas.

6. Máximo descuento (en euros) de las piezas suministradas.

7. Número, nombre y diferencia entre precio de venta y precio de compra de la(s) pieza(s) que suministran los vendedores de Alicante.

8. Máximo, mínimo y media de precio de venta de las piezas.

9. Cantidad total de piezas que sabemos nos pueden suministrar los proveedores.

10. Cantidad de vendedores de nuestra BD.

11. Total de la diferencia en euros entre lo pagado por compra de artículos y sus respectivos precios de suministro ofrecidos en su día por los proveedores si el segundo precio es menor que el primero.

Page 67: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

67

group by

INFORMACIÓN AGRUPADA

Objetivos:

• Obtención de información calculada sobre grupos de filas.

Contenidos

• GROUP BY • Resolución de requerimientos.

Clasificación de información en función de algún criterio especificado mediante la cláusula GROUP BY.

LA CLÁUSULA GROUP BY Supongamos que queremos obtener la cantidad de asignaturas que imparte cada profesor:

select p.dni, nombre, count( * ) from profesores p, imparte i where p.dni = i.dni group by p.dni, nombre

resultado: dni nombre ( count ) 21111222 EVA GOMEZ 2 21333444 RAFAEL ROMERO 1

En esta ocasión, y por la utilización de la cláusula group by, la cuenta de valores distintos de la columna asignatura se calcula en base a cada profesor de nuestra BD que imparte alguna asignatura.

El criterio de agrupación se forma con al menos todas las columnas no calculadas de la lista de la cláusula select.

• No se pueden poner columnas no calculadas en la select que no aparezcan en la group by.

select p.dni, nombre, count( * ) from profesores p, imparte i where p.dni = i.dni group by p.dni

resultado: ERROR

Page 68: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

68

• Si se pueden poner más columnas en la lista del group by que en la de la select. select nombre, count( * ) from profesores p, imparte i where p.dni = imparte.dni group by p.dni, nombre

resultado: nombre ( count(*) ) EVA GOMEZ 2 RAFAEL ROMERO 1

where y group by Cuando se utiliza la cláusula where, aparte de enlazar tablas por columnas comunes, como

PROFESORES e IMPARTE por profesores.dni e imparte.dni respectivamente, se puede utilizar para eliminar ciertas filas del cálculo.

Así, si queremos calcular cuantas asignaturas imparte cada profesor sin contar Fundamentos de las Bases de Datos, escribiremos la siguiente sentencia.

select nombre, count( * ) from profesores p, imparte i where p.dni = i.dni and asignatura <> 'FBD' group by p.dni, nombre

resultado: nombre ( count(*) ) EVA GOMEZ 1 RAFAEL ROMERO 1

ATRIBUTOS NO CLAVE EN EL GROUP BY Los únicos atributos que aseguran la identificación de una tupla respecto de las demás son los que

forman la clave primaria (en general, la clave candidata).

Así, si la clave primaria de una tabla de personas (profesores o alumnos, por ejemplo) es el D.N.I., podemos decir sin equivocarnos que no habrá duplicados en este atributo. No obstante, el nombre no será clave y, por lo tanto, admite duplicados. Es decir, es perfectamente posible encontrar a dos personas distintas (con números de D.N.I. diferentes, obviamente) que se llamen igual (nombres y apellidos).

Si, por ejemplo, agrupamos datos por el nombre y no por el D.N.I. podemos obtener información en una única fila de dos personas diferentes que se llaman igual. Sea una ocurrencia tal como ésta:

CLIENTE INGRESO DNI NOMBRE OPERACIÓN CLIENTE INGRESO 21 JUAN 1 21 1000 22 JUAN 2 22 2000 3 22 3000

Page 69: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

69

select nombre, avg( ingreso ) media from cliente, ingreso where dni = cliente group by nombre

resultado: nombre media JUAN 2000

Puesto que el nombre es el mismo para los dos clientes, la agrupación contabiliza todas las ocurrencias de ingreso como de uno sólo. Sin embargo, si introducimos en la lista de columnas del GROUP BY aquellas que son su clave primaria:

select nombre, avg( ingreso ) media from cliente, ingreso where dni = cliente group by dni, nombre

resultado: nombre media JUAN 1000 JUAN 2500

Es evidente que, si queremos saber exactamente de a qué cliente nos referimos en cada tupla del resultado, debemos incluir la clave primaria como atributo de la relación derivada de la ejecución de la select.

En general, y aunque no afecte al resultado, evitaremos la no inclusión de atributos clave en la cláusula group by.

ORDENACIÓN DE LA SALIDA En la cláusula order by podemos especificar la expresión tal cual aparece en la select.

select dni, count( * ) asignaturas from profesores group by p.dni, nombre order by count( * )

resultado: dni asignaturas 21333444 1 21111222 2

O bien podemos utilizar una alias para la columna (asignaturas en este ejemplo) o el orden de la columna empezando por la izquierda (la función está en la tercera columna en este ejemplo):

select dni, count( * ) asignaturas from profesores group by p.dni, nombre order by asignaturas select dni, count( * ) asignaturas from profesores group by p.dni, nombre order by 2

resultado: dni asignaturas 21333444 1 21111222 2

Page 70: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

70

CONSULTAS GROUP BY NOTA: es muy recomendable, aunque no se especifique explícitamente en el

requerimiento, que la salida se ordene ascendentemente (por defecto) por las columnas no calculadas de la lista de la cláusula select.

NOTA: así mismo, se deben etiquetar las columnas calculadas.

1. Obtener para cada pieza, nombre de la pieza, precio de venta, y la media de la diferencia entre el precio de venta y el de suministro.

2. Obtener para cada número de pedido, el precio pagado en total por ese pedido, la cantidad pedida total así como la diferencia entre cantidad pedida total y cantidad recibida total.

3. Obtener la cantidad de vendedores de cada empresa, indicando cantidad y nombre de la misma, ordenado descendentemente por cantidad de empleados.

4. Obtener, por pieza solicitada, la máxima diferencia entre cantidad pedida y cantidad recibida de entre todas las veces en que fue servida.

5. Obtener para cada pieza, el número de la pieza y el número total de vendedores que nos pueden suministrar esa pieza.

6. Obtener número de pieza y número total de vendedores que la pueden suministrar para piezas de más de 250 de precio de venta.

7. De cada pieza obtener el precio unitario medio de suministro.

8. De cada pieza de precio de venta mayor que 250 obtener el precio medio de suministro.

9. Obtener la media de las ventas (en euros) realizadas por cada vendedor de cada pieza.

10. Obtener la cantidad de pedidos efectuados por fecha y el total pagado por las mercancías.

11. Calcular las ganancias (precio de compra menos precio de suministro por la cantidad recibida) de cada vendedor que ha efectuado alguna venta.

12. Calcular por número de pedido, la media de la diferencia entre el precio de compra y el de suministro (que nos ofertaba el vendedor al que se le solicitó el pedido) de las líneas de cada pedido.

13. Calcular para cada pieza, el tanto por ciento de beneficios del precio de venta al público respecto al precio medio de compra de todas las compras que se han realizado de la pieza

14. Obtener, por cada pieza solicitada, cuántos vendedores la podrían suministrar, ordenado alfabéticamente por la descripción de la pieza y eliminando aquellas compradas a proveedores de Alicante.

Page 71: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

71

group by - having

SELECCIÓN DE INFORMACIÓN

AGRUPADA Objetivos:

• Establecer selecciones sobre información agrupada.

Contenidos

• HAVING. • Resolución de requerimientos.

LA CLÁUSULA HAVING Al igual que la cláusula where selecciona filas, la cláusula having selecciona grupos; si en la

where la condición que se especifica afecta a las tuplas de toda la tabla, el group by efectúa los cálculos en función de esa selección previa y da como resultado una tabla con la información calculada para cada grupo. Sobre esta última el having eliminaría aquellas tuplas que no cumplen la condición.

Normalmente, where selecciona sobre los datos almacenados en la tabla y having sobre la información calculada.

Supongamos que queremos saber cuantas asignaturas imparte cada profesor pero únicamente en el caso de que imparta 2 ó más asignaturas:

select p.dni, nombre, count( * ) asignaturas from profesores p, imparte i where p.dni = i.dni group by p.dni, nombre having count(*) >= 2 order by nombre

resultado: dni nombre asignaturas 21111222 EVA GOMEZ 2

Page 72: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

72

select p.dni, nombre, count( * ) asignaturas from profesores p, imparte i where p.dni = i.dni and asignatura <> 'FBD' group by p.dni, nombre having count(*) >= 2 order by nombre

resultado: dni nombre asignaturas

En la expresión del having no se pueden utilizar los alias de las columnas (asignaturas) en este caso.

Veamos, cláusula a cláusula, los efectos de esta última orden:

1. la cláusula where ha eliminado las tuplas de imparte de código de asignatura FBD.

2. la cláusula group by calcula, para cada profesor, el número de asignaturas que imparte. Puesto que no contamos FBD, Eva GOMEZ sólo imparte, igual que Rafael Romero, una única asignatura.

3. la cláusula having elimina del resultado del paso anterior todas aquellas tuplas con un valor en la cuenta de filas menor que 2. El resultado es vacío puesto que ninguno de los grupos supera la condición.

CONSULTAS GROUP BY - HAVING

1. Nombre de las empresas que tienen más de dos vendedores.

2. Números de pedido que tengan más de tres líneas de pedido.

3. Números de pedido donde el total de piezas pedidas es mayor que 40.

4. Obtener los números de pedido donde el precio total sea superior a 1000.

5. Para las piezas que se hayan ofertadoa un precio unitario medio mayor que 260 obtener el número de pieza, el máximo precio unitario, y la cantidad de suministradores.

6. Para las piezas que se ofrecen a un precio unitario medio mayor que 260 (sin tener en cuenta los suministros menores de 250) obtener el número de pieza, el máximo precio unitario, y la cantidad de suministradores.

7. Obtener aquellos números de pedido y fecha en que se confeccionaron cuya cantidad de artículos pedidos sea superior a 30 y la recibida inferior a 10.

8. Obtener el número de pieza y el precio unitario medio de aquellas piezas que tarden de media 14 días como máximo en ser suministradas (diassum=tiempo de suministro).

9. Obtener los números de pedido, precio de compra y cantidad pedida de los números de línea 1 y recibidas en fecha 10-05-92.

10. Obtener el número, el nombre y el precio máximo unitario de las piezas cuyo precio de venta sea mayor que 250 o menor que 170, su descuento medio oscile entre 10 y 17 y que tengan un precio unitario medio total superior a 150, ordenado por precio máximo.

11. Determinar el número total de proveedores que pueden suministrar la pieza 'P-0001-33’.

12. Para cada pieza, de la que se tiene información sobre sus posibles vendedores, obtener el número de pieza, y sus precios unitarios máximo y mínimo, exceptuando la información referida al vendedor número 1.

Page 73: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

73

13. Dar una relación del nombre de las piezas que nos pueden suministrar más de dos proveedores.

14. Obtener el número y el nombre del vendedor así como el número y nombre de las piezas de precio unitario mayor que 200 que nos puedan suministrar. El resultado se dará ordenado por número y nombre de vendedor y por nombre de la pieza.

Page 74: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

74

Page 75: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

75

subselect

CONSULTAS ANIDADAS Objetivos:

• Utilizar el resultado de una sentencia select para establecer las condiciones de otra sentencia select.

Contenidos

• Subqueries. • operadores de comparación escalar. • IN, ALL, ANY, [NOT]. • Resolución de requerimientos.

CONSULTAS ANIDADAS (SUBQUERIES) En la condición de búsqueda de la orden select (en la cláusula where o en la having) también

podemos:

• comparar una expresión con el resultado de otra orden select • determinar si el valor de una expresión está incluido en los resultados de otra orden select • preguntar si una orden select ha seleccionado filas.

Cuando una orden select se encuentra dentro de la cláusula where de otra select recibe el nombre de subconsulta (subquery). Por ejemplo :

select descripcion, creditos from asignaturas where creditos = ( select min(creditos) from asignaturas )

resultado: descripcion creditos Historia de la Informática 4.5

En primer lugar se calcula la select anidada (entre paréntesis) y se obtiene el valor mínimo

para la columna créditos de la tabla asignaturas. Con ese valor se compara tupla a tupla y se obtiene la asignatura (o asignaturas) cuya cantidad de créditos es igual al mínimo.

sintaxis general de la subconsulta

expresión op_comparación { ALL | [ ANY | SOME ] } ( orden select ) expresión [ NOT ] IN ( orden select ) [ NOT ] EXISTS ( orden select )

Los valores posibles a devolver por una orden select anidada son :

• nada • un valor único (una fila y una columna), • un conjunto de valores (varias filas y una columna).

Page 76: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

76

Siempre que la subselect devuelva algo, únicamente será en una y nada más que una columna (salvo el operador EXISTS).

DEVOLUCIÓN DE UN ÚNICO VALOR

expresión op_comparación ( orden select )

Podemos utilizar los operadores de comparación para preguntar si el valor de una determinada expresión es mayor, menor, igual, etc. que el resultado de la subselect, siempre y cuando ésta devuelva una única fila y una única columna, es decir, un valor simple.

En general serán órdenes select que calculan una función agregada (sum, min, max, avg, count).

select descripcion from asignaturas where creditos = ( select min(creditos) from asignaturas )

No sería correcto, porque la subselect devuelve más de una fila, la siguiente orden :

select descripcion from asignaturas where creditos = ( select creditos from asignaturas where creditos < 9 )

DEVOLUCIÓN DE UNA LISTA DE VALORES

expresión op_comparación ALL | [ ANY | SOME ] ( orden select )

Cuando la tabla resultado contiene más de una fila (pero una única columna, insistimos) hay que utilizar un modificador para el operador de comparación.

Nombre de la asignatura que tiene el mínimo número de créditos (es equivalente al primer ejemplo) :

select descripcion from asignaturas where creditos <= ALL ( select creditos from asignaturas )

resultado: descripcion creditos Historia de la Informática 4.5

En este caso, el número en créditos de la asignatura tiene que ser menor o igual que todos (all) los valores obtenidos en la subconsulta (que es la relación de créditos de todas las asignaturas).

Page 77: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

77

Nombre de las asignaturas que no tienen el mínimo número de créditos :

select descripcion from asignaturas where creditos > ANY ( select creditos from asignaturas )

resultado: creditos descripcion 6 Fundamentos de las Bases de Datos 6 Diseño y Gestión de Bases de Datos 6 Programación Concurrente 9 Fundamentos de la Programación

Serían todas aquellas asignaturas cuyos créditos superasen al menos a uno (any) de los valores devueltos por la subconsulta. El modificador some es equivalente a any.

Otra forma de expresar el mismo requerimiento :

select descripcion from asignaturas where creditos != ( select min(creditos) from asignaturas )

Supongamos que deseamos obtener el nombre de los profesores que imparten una asignatura que no sea la máxima en número de créditos :

select nombre from profesores p, asignaturas a, imparte i where p.dni = i.dni and i.asignatura = a.codigo

and creditos < ANY ( select creditos from asignaturas )

resultado: nombre Eva GOMEZ Rafael Romero

expresión [ NOT ] IN ( orden select )

También podemos consultar la pertenencia de un valor a la lista de valores devuelta por la subconsulta.

Obtener todos los datos de los profesores que imparte alguna asignatura :

select * from profesores where dni IN ( select dni from imparte )

O dicho de otra manera : datos de los profesores cuyo dni aparece en la tabla imparte.

En este caso daría lo mismo procesar la orden :

select p.* from profesores p, imparte i where p.dni = i.dni

Se verá más clara la utilidad de este operador si preguntamos justo lo contrario.

Page 78: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

78

Obtener todos los datos de los profesores que no imparten asignaturas :

select * from profesores where dni NOT IN ( select dni from imparte )

Por último, veamos que algunos de estos operadores son equivalentes :

expresión IN (orden select) ≡ expresión =ANY (orden select) expresión NOT IN (orden select) ≡ expresión !=ALL (orden select)

CONSULTAS SUBSELECT

1. Obtener todos los datos de los vendedores a los que se les han solicitado más pedidos que a todos los demás.

2. Número y nombre de los vendedores que no ofertan ninguna pieza.

3. Número y nombre de los vendedores a los que se les ha solicitado algún pedido.

4. Número y nombre de los vendedores a los que no se les ha solicitado pedidos.

5. Nombre de la empresa que ofrece la pieza más barata de precio de suministro.

6. Número y descripción de la pieza más cara (precio de venta).

7. Para cada pieza que se ofrece en la lista de suministros, obtener el número de pieza, y sus precios unitarios máximo y mínimo, exceptuando aquellos suministrados por el vendedor número 1.

8. Número de pedido y precio total pagado del pedido más caro.

9. Número y nombre del vendedor al que se le ha solicitado el pedido más caro.

10. Número, descripción y precio de venta de los monitores que no han sido nunca solicitados.

11. Calcular, por cada número de vendedor, la cantidad de piezas distintas que ha vendido, para aquellos vendedores pertenecientes a la empresa con más proveedores.

12. Nombre de los suministradores que pueden suministrar al menos alguna de las piezas que puede suministrar el vendedor número 5.

13. Listar los vendedores que sean de la misma provincia que el vendedor número 100.

14. Obtener los nombres de los vendedores de la misma empresa que Luis García.

15. Número y descripción de las piezas cuyo precio medio de suministro esté por encima del mayor precio de compra pagado por ella.

16. Número, nombre, empresa en la que trabaja y número de piezas que puede suministrar el vendedor que tiene la media más alta de piezas servidas.

17. Nombre de la empresa con mayor importe de ventas.

18. Número y descripción de la pieza que ha sido pedida más veces.

19. Número y descripción de las piezas que pueden ser suministradas por proveedores de la Comunidad Valenciana o que pueden ser suministradas por el vendedor que ha realizado la menor venta (pedido de importe más bajo)

Page 79: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

79

20. Número de vendedor, número de pieza y descuento para aquellas piezas cuyo precio de venta supere en más del 15% la media del precio de compra de los pedidos en los que aparece.

21. Cantidad de piezas a la venta de las que no tenemos información sobre sus posibles suministradores.

Page 80: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

80

Page 81: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

81

subselect - exists

CONSULTAS ANIDADAS II Contenidos

• El operador EXISTS. • Resolución de requerimientos.

EL OPERADOR EXISTS [ NOT ] EXISTS ( orden select )

El operador exists nos informa si una subconsulta ha devuelto algún resultado, o lo que es lo mismo, si la tabla resultado tiene alguna fila.

Exists devuelve verdadero si hay al menos una tupla en la relación derivada y falso si la relación derivada es vacía.

Supongamos que queremos conocer si algún profesor imparte todas las asignaturas :

select nombre from profesores p where not exists ( select codigo from asignaturas a where not exists ( select asignatura from imparte i where i.asignatura=a.codigo and p.dni=i.dni ) )

Vamos a leer el requerimiento siguiendo las apariciones del operador exists dentro de las sucesivas órdenes select : Nombre de los profesores tales que no hay ninguna asignatura que no imparta él.

Supongamos que la forma que tiene el SGBD de resolver esta sentencia es la siguiente :

• En la primera select recorremos la tabla de profesores. • Para cada profesor, la segunda select recorre la tabla de asignaturas. • Para cada profesor y asignatura comprueba que el primero imparte la segunda.

Una vez que ha fijado el profesor y la asignatura, la última subconsulta dará como resultado verdadero si la imparte y falso en caso contrario (devolverá una tupla o no devolverá nada).

Supongamos un profesor que no imparte al menos una de las asignaturas de nuestra base de datos. Cuando el SGBD esté resolviendo la última subselect para ese profesor y esa asignatura, como no están relacionados, no devolverá ninguna tupla : el resultado del segundo exists es falso, y, como está negado, finalmente verdadero (ese profesor no imparte esa asignatura).

Por lo tanto, para la primera subselect, ya existe una asignatura que obtiene en la cláusula where un valor verdadero : esa asignatura saldrá en la tabla resultado. Como ésta última tiene al menos una fila, el primer exists será verdadero, y, como está negado, finalmente falso. El profesor no imparte todas las asignaturas de nuestra base de datos.

Un profesor que imparta todas las asignaturas obtendrá siempre una fila en la última subselect y, por lo tanto, ninguna asignatura aparecerá como resultado de la primera subselect, el correspondiente exists será falso, y por efecto del operador de negación la condición será cierta : ese profesor aparecerá en la solución.

En nuestra base de datos Ejemplo no hay ningún profesor que imparta todas las asignaturas.

Page 82: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

82

Aunque puede inducir a error, por su traducción intuitiva del inglés al español, no se deben confundir nunca los operadores IN y EXISTS : el primero devuelve una lista de valores, mientras que el segundo devuelve un valor de verdad; la sintaxis también es muy diferente.

CONSULTAS SUBSELECT - EXISTS

1. Nombre de los vendedores que pueden suministrar todas las piezas.

2. Nombre de los vendedores que no pueden suministrar ninguna pieza, ordenados alfabéticamente.

3. Numero y descripción de las piezas que se han solicitado en todos los pedidos del vendedor 1.

4. Nombre de las empresas que cumplen que todos sus vendedores son de la Comunidad Valenciana, ordenadas alfabéticamente.

5. Número y nombre de todos los vendedores de la ciudad de Alicante.

6. Empresas que no han servido ninguna pieza.

7. Empresas que han servido la(s) pieza(s) de mayor precio de venta.

8. Numero de los pedidos cuyas piezas tienen todas un precio de venta mayor que la mitad del precio máximo de venta.

9. Obtener todos los datos de los vendedores que sirvieron los pedidos del requerimiento anterior.

10. Número y nombre de los vendedores que han servido algún pedido (utilizando obligatoriamente EXISTS).

11. Número y nombre de la pieza de menor precio de suministro (utilizando EXISTS).

12. Nombre de los vendedores a los que se les haya solicitado más de dos pedidos (utilizando subconsultas).

13. Número de pedido, fecha y número de vendedor del pedido más caro (utilizando subconsultas).

Page 83: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

83

adicionales 1

EJERCICIOS ADICIONALES

CONSULTAS

1. Toda la información de las piezas que puedan ser suministradas por vendedores de empresas cuyo nombre empieza por 'H'.

2. Piezas que el vendedor numero 1 ofrece en la lista de suministros y que han sido servidas en algún pedido

3. Vendedores que pueden suministrarnos piezas que se venden al público con un precio de venta entre 50 y 100 y que esa pieza ha sido solicitada en algún momento (no necesariamente a ellos)

4. Nombre de las empresas de Alicante a las que se ha comprado algún monitor

5. Nombre y numero de las piezas que se han solicitado en algún pedido ordenadas por el nombre

6. Para cada pieza comprada, número de pieza y diferencia en euros entre el precio de compra y el de suministro del vendedor al que se le compró, ordenado descendentemente por dicha cantidad.

7. Numero de vendedor y empresa para la que trabaja de aquellos que han vendido alguna pieza por un precio mayor que el estipulado por ellos en la lista de suministros

Page 84: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

84

Page 85: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

85

adicionales 2

EJERCICIOS ADICIONALES

CONSULTAS

1. Obtener el nombre de los vendedores y la cantidad de piezas que pueden suministrar, ordenado alfabéticamente por vendedor.

2. Obtener el número y el nombre de los vendedores y la cantidad de piezas que pueden suministrar ordenado alfabéticamente por vendedor.

3. Obtener el nombre de las piezas, la media del precio unitario de cada pieza y el precio de venta de todas las piezas de las que conocemos posibles suministradores.

4. Para cada pedido obtener el número de líneas que tiene, el número y nombre del vendedor y la fecha del pedido.

5. Obtener el nombre de las piezas, la media del precio unitario de cada pieza y el precio de venta de todas las piezas que puedan sernos suministradas por más de tres proveedores.

6. Obtener los números y nombres de los vendedores que han servido algún pedido con más de tres artículos diferentes.

7. Obtener número y nombre de vendedores a los que les hayamos solicitado algún pedido.

8. Obtener el nombre de las piezas, la media del precio unitario de cada pieza y el precio de venta de todas las piezas de precio unitario medio mayor que 100 y que puedan ser suministradas por más de dos proveedores.

9. Obtener para cada pieza, el nombre de las pieza, la media del precio unitario de suministro y el precio de venta, para las piezas de precio de venta mayor que 300, teniendo en cuenta que la media de los precios unitarios debe estar entre 100 y 280. Ordenar el resultado por el nombre de la pieza.

10. Obtener número y nombre de las piezas que tengan una diferencia entre precio de venta y media de precio de suministro (preciounit) menor del 20% del precio de venta.

Page 86: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

86

Page 87: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

87

adicionales 3

EJERCICIOS ADICIONALES

CONSULTAS

1. Obtener para los vendedores de la provincia de Alicante, el número de vendedor, su nombre y la cantidad total de pedidos que se les ha solicitado.

2. Obtener la cantidad total de piezas que se solicitaron en el año 1992.

3. Obtener el número de pedido, el importe total, y el numero y nombre del vendedor al que se les solicitó, para los pedidos de importe total superior a 10000 euros. Ordena el resultado por el importe total.

4. Para cada pieza que pueda ser suministrada a un precio medio unitario inferior a 10 euros, obtener el número de la pieza, su nombre, el precio máximo al que nos la han ofrecido, el precio mínimo y la cantidad de vendedores que nos la pueden suministrar.

5. Para los pedidos que nos han sido servidos en más de un día, obtener el número de pedido, el número del vendedor al que se le solicitó, su nombre, y la cantidad de días distintos en los que nos han servido las piezas solicitadas.

6. Para las empresas que tengan un único vendedor, obtener el nombre de la empresa y la cantidad total de pedidos que se le han solicitado, y el importe total entre todos los pedidos.

7. Para las piezas recibidas en domingo, obtener el número de la pieza, su nombre y el número y nombre del vendedor al que se le solicitaron. Ordena el resultado por el nombre de la pieza.

Page 88: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

88

Page 89: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

89

adicionales 4

EJERCICIOS ADICIONALES

CONSULTAS

1. Número y nombre de los vendedores a los que les hemos solicitado algún pedido en el año 1995 pero no les hemos solicitado ninguno en el año 1992.

2. Obtener el número y el nombre las piezas que puedan sernos suministradas por más de dos vendedores de la provincia de Alicante, y que en total (entre todos los pedidos solicitados a todos los vendedores) hayamos pedido más de 500 unidades.

3. Obtener el nombre de las empresas de las que tengamos más de 1 de un vendedor de Alicante y no se les haya hecho ningún pedido (a ninguno de sus vendedores) antes del año 1995.

4. Obtener el número y nombre de las piezas que nunca hemos solicitado.

5. Obtener el número de los vendedores (numvend) que nos hubiesen podido servir todo lo que se solicita en las líneas 1, 2 y 3 del pedido número 1.

6. Obtener para los vendedores de Alicante o Madrid, el número y nombre de vendedor junto con el importe total que les hemos pagado a través de todos los pedidos que se les ha solicitado.

Page 90: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

90

Page 91: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

91

adicionales 5

EJERCICIOS ADICIONALES

CONSULTAS

1. Obtener para los pedidos con un importe total entre 400 y 600 euros, el número de pedido, el número y nombre del vendedor al que se le solicitó, y la fecha del pedido.

2. Obtener para las piezas cuyo precio de suministro oscila entre 10 y 15, el número de la pieza, su nombre, y la cantidad de vendedores que nos la pueden suministrar a ese precio.

3. Obtener para los vendedores a los que les hayamos pagado en total (entre todos sus pedidos) más de 3000 euros, el número y nombre de vendedor junto con el importe total que les hemos pagado, y el total de pedidos que les hemos hecho.

4. Obtener para el número y nombre de los vendedores de Alicante a los que se les haya solicitado alguna pieza, de la que nos habían indicado que su plazo de suministro sería superior a una semana, junto con el número y nombre de la pieza, y la cantidad de pedidos distintos en los que se les ha solicitado. Ordena el resultado por la última columna.

5. Obtener el nombre de la empresa que tiene más de tres vendedores, y al menos dos de ellos son de la provincia de Alicante.

6. Obtener los nombre y empresas de los vendedores que no son de la Comunidad Valenciana, de los que se desconoce el teléfono.

Page 92: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

92

Page 93: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

93

adicionales 6

EJERCICIOS

CONSULTAS

1. Obtener el nombre de la pieza (o piezas) y su precio unitario máximo de la pieza de precio unitario medio más bajo.

2. Nombre del vendedor y media de todos sus precios de suministro para los vendedores que viven en la misma ciudad que algún vendedor de apellido García.

3. Para la pieza (o piezas) de precio de venta mayor, obtener el nombre de la pieza y número total de vendedores que la pueden suministrar.

4. Obtener el nombre de vendedor para los vendedores cuya media de precio unitario de suministro sea máxima.

5. Obtener el nombre de la pieza y su precio unitario medio de la pieza más barata de precio de venta.

6. Nombre y empresa de los vendedores de la ciudad a la que se le ha solicitado más piezas.

7. Número de pedido, y número y nombre de vendedor del pedido que no es el de menor importe de venta (preciocompra*cantrecibida) siendo el año del pedido posterior al 1992 (>1992).

8. Nombre de los vendedores a los que se les haya solicitado más de dos pedidos en los que se sirvan discos duros.

9. Número de pieza, descripción y precio de venta de la pieza que más veces se ha pedido.

10. Número de pieza, descripción, precio medio de suministro y descuento máximo de las piezas que proceden de la misma ciudad que la empresa Mecemsa y que se han solicitado 2 veces o más.

Page 94: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

94

Page 95: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

95

adicionales 7

EJERCICIOS CONSULTAS

1. Número y nombre de los vendedores que oferten alguna de las piezas que pueden ser suministradas por el vendedor número 1, pero que no oferten ninguna de las que puedan ser suministradas por el vendedor número 2.

2. Obtener el número y el nombre de los vendedores y la cantidad de piezas que pueden suministrar a un precio entre 15 y 20 euros, ordenado por el nombre de vendedor.

3. Obtener, para el vendedor que cumple que la diferencia de precio al que le compramos una pieza y el precio que nos había ofrecido por ella sea máxima, el número de vendedor, su nombre y la diferencia media entre el precio al que nos vende las piezas y el que nos había ofrecido por las mismas.

4. Obtener el número de pieza de los teclados que nos han sido servidos en el mayo de cualquier año.

5. Obtener un listado en el que figure el número y nombre de la pieza , junto con el número y nombre de vendedor que nos ha ofertado la pieza, pero al que nunca se la hemos solicitado.

6. Obtener los números y nombres de los vendedores que nos han servido más de tres artículos diferentes.

Page 96: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

96

Page 97: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

97

SOLUCIONES SELECT1 Muchas de las soluciones también se muestran en álgebra relacional (AR) y cálculo

relacional de tuplas (CRT), que son temas que se tratarán más adelante en las clases de teoría. En AR y CRT los resultados son relaciones, por lo tanto todas las soluciones que se muestran aquí corresponden al enunciado al que se esté dando respuesta, pero eliminando duplicados. En CRT se consideran declaradas correctamente todas las variables utilizadas.

--1 select numpieza from pieza En AR PIEZA[numpieza] En CRT {P.numpieza/PIEZA(P)} --2 select nompieza from pieza where preciovent < 1000 En AR PIEZA donde preciovent<1000[nompieza] En CRT {P.nompieza / PIEZA(P) ∧ P.preciovent<1000} --3 select numpieza, nompieza, preciovent from pieza where preciovent > 10 or preciovent < 1 order by preciovent (la ordenación no se puede expresar ni En CRT ni En AR) En AR PIEZA donde preciovent>10 o preciovent<1 [numpieza,nompieza,preciovent] En CRT { P.nompieza, P.nompieza, P.preciovent / PIEZA(P) ∧ P.preciovent>1000 ∧ P.preciovent<10000} --4 select numpieza, descuento from preciosum order by descuento desc En AR PRECIOSUM [numpieza, descuento] En CRT {P.numpieza, P.descuento / PRECIOSUM(P)} --5 select nomvend from vendedor where numvend < 6 --6 select distinct nomvend from vendedor where numvend < 6 En AR VENDEDOR donde numvend<6 [nomvend] En CRT {V.nomvend / VENDEDOR(V) ∧ V.numvend<6} --7 select numvend, nomvend from vendedor where numvend < 6 En AR VENDEDOR donde numvend<6 [numvend, nomvend] En CRT {V.numvend, V.nomvend / VENDEDOR(V) ∧ V.numvend<6} --8 select distinct numvend from preciosum --9 select numvend, nomvend from vendedor where provincia = 'ALICANTE' --10 select nomvend, nombrecomer from vendedor where provincia = 'ALICANTE' or provincia = 'CASTELLON' or provincia = 'VALENCIA'

Page 98: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

98

--11 select numvend, diassum from preciosum where numpieza = 'P-0001-33'

SOLUCIONES SELECT2

--2 select distinct numpieza, provincia from preciosum ps, vendedor v where ps.numvend = v.numvend order by numpieza desc

(En AR y C.R.T. no se puede hacer order by) En AR Vendedor ∞ Preciosum [numpieza, provincia] En CRT {PS.numpieza, V.provincia/ Preciosum(PS) ∧ ∃ V(Vendedor(V) ∧ PS.numvend=V.numvend) }

--9 select preciounit from preciosum where numvend = 100 and numpieza='A-1001-L'

En AR Preciosum donde numvend=100 y numpieza=A-1001-L [precionuit] En CRT {PS.preciounit / Preciosum(PS) ∧ numvend=100 ∧ numpieza=A-1001-L }

--17 select p.numpieza, nompieza from preciosum ps, pieza p where ps.numpieza=p.numpieza and (numvend = 2 or numvend = 4)

En AR Pieza ∞ Preciosum donde numvend=2 o numvend=4 [numpieza, nompieza] En CRT {P.numpieza, P.nompieza/ Pieza(P) ∧ ∃ PR (Preciosum(PR) ∧ P.numpieza=PR.numpieza ∧ (numvend=2 ∨ numvend=4)) }

--19 select nompieza, l.numpieza, preciovent from pieza pz, pedido p,linped l where numvend = 1 and p.numpedido=l.numpedido and l.numpieza=pz.numpieza

En AR Pieza ∞ Linped ∞ Pedido donde numvend=1 [numpieza, nompieza, preciovent] En CRT {P.numpieza, P.nompieza P.preciovent/ Pieza(P) ∧ ∃ LP (Linped(LP) ∧ P.numpieza=LP.numpieza ∧ ∃ P (Pedido(P) ∧ LP.numpedido=P.numpedido ∧ numvend=1)) }

SOLUCIONES SELECT3 En AR y CRT no existe el operador LIKE, ni el operador IS NULL, así como tampoco se puede establecer un criterio para ordenar el resultado.

--1 select nompieza from pieza p, preciosum ps, vendedor v where p.numpieza = ps.numpieza and ps.numvend = v.numvend and nomvend like 'S%'

Page 99: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

99

--2 select nompieza from pieza p, preciosum ps, vendedor v where p.numpieza = ps.numpieza and ps.numvend = v.numvend and (nomvend like 'S% MARTIN %' or nomvend like 'S% MARTINEZ %') --3 select nomvend from vendedor where provincia in ('ALICANTE', 'VALENCIA', 'CASTELLON') order by nomvend

En AR Vendedor donde provincia=Alicante o provincia=Castellón o provincia=Valencia [nomvend] En CRT {V.nomvend / Vendedor(V) ∧ (provincia=Alicante ∨ provincia=Castellon ∨ provincia=Valencia)}

--7 select nomvend from vendedor where nomvend like 'M_R%' order by nomvend --12 select * from vendedor where telefono is not null order by nomvend

SOLUCIONES SELECT FECHA --1 select numpieza from inventario where fecharecuento=’15/10/1992’ --2 select numpieza from inventario where fecharecuento >= '1/10/1992' and fecharecuento <='31/10/1992' --3 select numpedido, fecha from pedido where fecha >= '1/7/1992' and fecha <= '31/12/1992'; select numpedido, fecha from pedido where to_char(fecha,'YY') = '92' and to_char(fecha,'MM') >= 6; --4 select distinct nomvend from vendedor v, pedido pd, linped l where v.numvend = pd.numvend and pd.numpedido = l.numpedido and to_char(fecharecep,'YYYY') = 1992 and to_char(fecharecep,'MM') = 5 and to_char(fecharecep,'DD') <= 15 order by nomvend --7 select distinct pz.numpieza, nompieza from linped l, pieza pz where l.numpieza = pz.numpieza and to_char(fecharecep,'DD') = 10

Page 100: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

100

SOLUCIONES CREATE Algunas de las órdenes provocan errores, se debe identificar el origen del mismo. --1 tabla creada --2 ninguna fila seleccionada --3 1 fila creada --4 ERROR --5 1 fila creada --6 col1 col2 ---- ----

1 AA 2 BB

--9 tabla borrada --10 ERROR --11 tabla creada --12 1 fila creada 1 fila creada 1 fila creada 1 fila creada ERROR ERROR ERROR 1 fila creada 1 fila creada --13 create table listin

(apodo varchar2(10), nombre varchar2(25), telefono varchar2(9), primary key (apodo) );

--14 drop table listin; create table listin

(apodo varchar2(10), nombre varchar2(25), telefono varchar2(9), grado integer, primary key (apodo) );

--15 create table compra (orden integer, articulo varchar2(40), cantidad integer, formato varchar2(10), precioEstimado number(5,2), primary key (orden)

);

SOLUCIONES MANIPULACIÓN1 --1 create table listin (apodo varchar2(10), nombre varchar2(25), telefono varchar2(9), grado integer, primary key (apodo) ); insert into listin (apodo,nombre,grado) values ('semao','Paco Musoso',2); insert into listin (apodo,nombre,grado,telefono) values ('aguila','Luis Ligero',1,'555111222');

Page 101: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

101

insert into listin (apodo,nombre,grado,telefono) values ('largo','Juan Pitillo',1,'555111333'); insert into listin (apodo,nombre,grado)values ('sobrao','Cristobal Garcilaso',5); --2 create table amistad (grado integer, descripcion varchar2(20), primary key (grado) ); --3 drop table listin; create table listin (apodo varchar2(10), nombre varchar2(25), telefono varchar2(9), grado integer, primary key (apodo), foreign key (grado) references amistad(grado) ); --4 ERROR: No se puede insertar ninguna fila

restricción de integridad (BD1.SYS_C004090) violada - clave principal no encontrada

SOLUCIONES MANIPULACIÓN2 -- 1 update inventario set fecharecuento=’01/01/2003’; -- 2 update inventario set cantminima=cantdisponible where cantdisponible<cantminima; -- 3 update vendedor set telefono='SIN TLFNO' where telefono is null; -- 4 update vendedor set calle='CENTRAL, 5', provincia='SALAMANCA', ciudad='SALAMANCA' where provincia='TOLEDO'; -- 5 update pieza set nompieza='SIN DESCRIPCION' where nompieza is null; -- 9 update pedido set numvend=1000 where numvend=200; --restricción de integridad violada -- 10 update pedido set numpedido=4 where numpedido=8; update pedido set numpedido=1 where numpedido=5; --restricción única violada update pedido set numpedido=8 where numpedido=2; --restricción de integridad violada, encontrado registro secundario update pedido set numpedido=3 where numpedido=2; --restricción única violada -- 13 update pieza set nompieza=(select nompieza from pieza where preciovent=7) where nompieza=’SIN DESCRIPCION’; --La subconsulta devuelve más de una fila

Page 102: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

102

-- 16 update preciosum set (numpieza, preciounit) = (select numpieza, preciovent from pieza where nompieza = ‘DISKETTE 1.44 PANASONIC’) where numvend=200; --se viola la clave primaria de preciosum, ya que hay varias filas para --ese número de vendedor -- 17 update pedido set fecha=to_date(sysdate,’DDMMYYYY’) where numvend=3; -- 19 update inventario set periodorecuen = (select periodorecuen from inventario where fecharecuento > ‘1/01/2003’) where fecharecuento < ‘01/01/2003’;

--la subconsulta puede devolver más de una fila

SOLUCIONES MANIPULACIÓN3 -- 1 delete from vendedor where numvend = 1; -- 2 El vendedor 1 tiene suministros (PRECIOSUM) y pedidos (PEDIDO). Dada la definición

de claves ajenas en PRECIOSUM, el borrar la fila de este vendedor provoca el borrado automático de todas sus filas en PRECIOSUM.

También ocurre lo mismo en PEDIDOS, pero esta tabla está, a su vez, referenciada en LINPED con una clave ajena que también tiene establecida la PROPAGACIÓN como mecanismo para mantener la integridad referencial ante borrados en PEDIDO: todas las filas de los pedidos del vendedor 1 (los pedidos 1, 2, y 5) son eliminadas también.

Resumiendo, por la definición de claves ajenas en la BD, el borrado del vendedor 1 afecta a las tablas PRECIOSUM, PEDIDO y LINPED, quedando PIEZA e INVENTARIO como estaban ya que en ellas no se generan problemas de integridad referencial.

-- 3 delete from vendedor where numvend = 3; -- 4 El vendedor 3 tiene suministros (PRECIOSUM) y pero no pedidos. Borrar la fila de

este vendedor provoca el borrado automático de todas sus filas en PRECIOSUM, pero no se producen más operaciones en ninguna otra tabla.

-- 5 delete from vendedor where numvend = 8001; -- 6 El vendedor 8001 no tiene suministros (PRECIOSUM) ni pedidos. Por tanto, la única

fila eliminada es la propia del vendedor en la tabla VENDEDOR. -- 7 delete from pedido where numpedido = 3; -- 8 El borrado del pedido 3 provoca la eliminación automática de todas sus líneas de

pedido pero nótese que el vendedor 2 (al que pertenecía este pedido) sigue estando en la tabla VENDEDOR (como ocurría en las operaciones anteriores, por cierto, con las líneas de pedido borradas automáticamente pero no sus piezas en PIEZA). Los únicos problemas de integridad referencial, en este caso, se producen en LINPED.

-- 9 delete from pieza where numpieza = ‘O-0001-PP’; La pieza ‘O-0001-PP’ tiene referencias en la tabla PRECIOSUM (también en LINPED), y

como no se ha modificado la clave ajena en esta tabla, el sistema tiene como política asignada por defecto RECHAZAR: la operación ha generado un error.

-- 10 delete from preciosum where numpieza = ‘O-0001-PP’;

Page 103: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

103

-- 12 delete from pieza where numpieza = ‘O-0001-PP’; La pieza ‘O-0001-PP’ ya no tiene referencias en la tabla PRECIOSUM, pero sigue

manteniendo las de LINPED. En esta tabla se ha definido la ANULACIÓN como política ante borrados en PIEZA: todas las referencias a esta pieza se han sustituido por NULOS.

-- 14 delete from pieza where numpieza = ‘DD-0001-210’; La pieza ‘DD-0001-210’ no tiene referencias en la tabla PRECIOSUM puesto que las

hemos eliminado en la orden 13, pero sí las tiene en LINPED e INVENTARIO. En ambas tablas se ha elegido la ANULACIÓN para las clavea ajenas a PIEZA, pero mientras es posible aplicarla en LINPED, en INVENTARIO es imposible ya que la clave ajena no admite nulos (es clave alternativa al definirla como UNIQUE y NOT NULL simultáneamente). La operación no puede realizarse.

SOLUCIONES CONJUNTOS --1 select nombrecomer from vendedor v,pedido p where v.numvend=p.numvend UNION select nombrecomer from vendedor v, preciosum ps

where v.numvend=ps.numvend and numpieza='A-1001-L'

En AR Vendedor ∞ Pedido [nombrecomer] ∪ (Vendedor ∞ Preciosum donde numpieza = ‘A-1001-L’ [nombrecomer])

--2 select nombrecomer from vendedor v,pedido p where v.numvend=p.numvend INTERSECT select nombrecomer from vendedor v, preciosum ps

where v.numvend=ps.numvend and numpieza='A-1001-L' --o también: select nombrecomer from vendedor v,pedido p, preciosum ps where v.numvend=p.numvend and v.numvend=ps.numvend and numpieza='A-1001-L'

En AR Vendedor ∞ Pedido [nombrecomer] ∩ (Vendedor ∞ Preciosum donde numpieza = ‘A-1001-L’ [nombrecomer])

--3 En AR Vendedor ∞ Pedido [nombrecomer] - (Vendedor ∞ Preciosum donde numpieza = ‘A-1001-L’ [nombrecomer])

SOLUCIONES FUNCIONES --1 select numlinea, cantrecibida-cantpedida diferencia from linped where numpedido = 1 --2 select avg(abs(fecha-fecharecep)) mediarecep from linped l, pedido pd where pd.numpedido = 1 and l.numpedido = pd.numpedido --3 select count(distinct provincia) provincias from vendedor

Page 104: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

104

--4 select min(preciocompra-preciounit) minimo from preciosum ps, pedido pd, linped l where ps.numvend = pd.numvend and pd.numpedido = l.numpedido and l.numpieza = ps.numpieza --5 select avg(distinct preciovent) mediaventa from pieza

SOLUCIONES GROUP BY En AR y C.R.T. no hay definidas funciones agregadas por lo que muchos de los requerimientos nos los podríamos abordar, sobre todo si estas funciones agregadas aparecen en la cláusula SELECT.

--1 select nompieza, preciovent, avg(preciovent-preciounit) media from pieza p, preciosum ps where p.numpieza=ps.numpieza group by p.numpieza,nompieza,preciovent order by nompieza --2 select numpedido, sum(preciocompra*cantrecibida) precioPagado, sum(cantpedida) cantidadPedida, sum(cantpedida-cantrecibida) no_recibido from linped group by numpedido order by numpedido --3 select count(*) vendedores, nombrecomer from vendedor group by nombrecomer order by vendedores desc, nombrecomer --4 select numpieza, max(cantpedida-cantrecibida) maximo from linped group by numpieza order by numpieza --5 select numpieza, count(*) vendedores from preciosum group by numpieza order by numpieza --6 select ps.numpieza, count(*) vendedores from preciosum ps, pieza p where ps.numpieza = p.numpieza and preciovent >= 250 group by ps.numpieza order by 2 --7 select numpieza,avg(preciounit) precio_Sum_Medio from preciosum group by numpieza order by numpieza --13 select p.numpieza, max(preciovent)/avg(preciocompra)*100 from linped l, pieza p where l.numpieza=p.numpieza group by p.numpieza

order by p.numpieza

Page 105: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

105

SOLUCIONES GROUP BY - HAVING En AR y CRT no hay definidas funciones de agregados por lo que muchos de los requerimientos nos los podríamos abordar, sobre todo si estas funciones agregadas aparecen en la cláusula SELECT.

--1 select nombrecomer from vendedor group by nombrecomer having count(*)>2

En AR Define alias V1, V2 para VENDEDOR V1 × V2 × VENDEDOR donde V1.nombrecomer=V2.nombrecomer and V2.nombrecomer=Vendedor.nombrecomer and V1.numvend<>V2.numvend and V1.numvend<> VENDEDOR.numvend and V2.numvend<>Vendedor.numvend [V1.nombrecomer] En CRT {V1.nombrecomer | VENDEDOR(V1) ∧ ∃ V2(VENDEDOR(V2) ∧ V1.nombrecomer=V2.nombrecomer ∧ V1.numvend<>V2.numvend ∧ ∃ V3(VENDEDOR(V3) ∧ V2.nombrecomer=V3.nombrecomer ∧ V1.numvend<>V3.numvend ∧ V2.numvend<>V3.numvend))}

--2 select numpedido from linped group by numpedido having count(*)>3

En AR Define alias LP1, LP2, LP3 para LINPED LP1 × LP2 × LP3 × LINPED donde LP1.numpedido=LP2.numpedido and LP2.numpedido=LP3.numpedido and LP3.numpedido=LINPED.numpedido and LP1.numlinea<>LP2.numlinea and LP1.numlinea<> LP3.numlinea and LP1.numlinea<> LINPED.numlinea and LP2.numlinea<> LP3.numlinea and LP2.numlinea<>LINPED.numlinea and LP3.numlinea<> LINPED.numlinea [LP1.numpedido] En CRT {LP1.numpedido | LINPED(LP1) ∧ ∃ LP2 ∃ LP3 ∃ LP4 (LINPED(LP2) ∧ LINPED(LP3) ∧ LINPED(LP4) ∧ LP1.numpedido=LP2.numpedido ∧ LP1.numlinea<>LP2.numlinea ∧ LP1.numlinea<>LP3.numlinea ∧ LP1.numlinea<>LP4.numlinea ∧ LP2.numpedido=LP3.numpedido ∧ LP3.numpedido=LP4.numpedido ∧ LP2.numlinea<>LP4.numlinea ∧ LP3.numlinea<>LP4.numlinea) }

--3 select numpedido from linped group by numpedido having sum(cantpedida)>40 --4 select numpedido from linped l group by numpedido having sum(cantrecibida*preciocompra)>1000 --5 select numpieza, max(preciounit), count(*) from preciosum group by numpieza having avg(preciounit)>260 --6 select numpieza, max(preciounit) maximo, count(*) cuantos from preciosum where preciounit >= 250 group by numpieza having avg(preciounit)>260 --7 select p.numpedido, fecha from pedido p, linped l where p.numpedido=l.numpedido group by p.numpedido,fecha having sum(cantpedida)>30 and sum(cantrecibida)<10

Page 106: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

106

--10 select p.numpieza,nompieza,max(preciounit) maximo from pieza p,preciosum ps where ps.numpieza=p.numpieza and preciovent > 250 or preciovent < 170 group by p.numpieza,nompieza having avg(descuento) between 10 and 17 and avg(preciounit) > 150

order by maximo

SOLUCIONES SUBSELECT --1 select * from vendedor where numvend in (select numvend from pedido group by numvend having count(*) >= all(select count(*) from pedido group by numvend)) --2 select numvend, nomvend from vendedor where numvend not in (select numvend from preciosum) order by nomvend

En AR (VENDEDOR[numvend] ∼ PRECIOSUM[numvend]) ∞ VENDEDOR[numvend, nomvend] En CRT {V.numvend, V.nomvend / VENDEDOR(V) ∧ ⎤ ∃ PR(PRECIOSUM(PR) ∧ PR.numvend=V.numvend)}

--3a select v.numvend, nomvend from vendedor v, pedido p where v.numvend = p.numvend order by nomvend

En AR VENDEDOR ∞ PEDIDO [numvend, nomvend] En CRT {V.numvend, V.nomvend / VENDEDOR(V) ∧ ∃ P(PEDIDO(P) ∧ P.numvend=V.numvend)}

--3b select numvend, nomvend from vendedor where numvend in (select numvend from pedido) order by nomvend --11 select v.numvend,count(distinct numpieza) npiezas from vendedor v, pedido p, linped l where v.numvend=p.numvend and p.numpedido=l.numpedido and nombrecomer in (select nombrecomer from vendedor group by nombrecomer having count(*) >= all (select count(*) from vendedor group by nombrecomer)) group by v.numvend order by v.numvend --15 select p.numpieza, nompieza,avg(preciounit),max(preciocompra) from pieza p, preciosum ps, linped l where p.numpieza=ps.numpieza and ps.numpieza=l.numpieza group by p.numpieza, nompieza having avg(preciounit)>= (select max(preciocompra) from linped where linped.numpieza=p.numpieza)

Page 107: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

107

SOLUCIONES SUBSELECT - EXISTS

--1 select nomvend from vendedor v where not exists (select * from pieza pz where not exists (select * from preciosum where numvend = v.numvend and numpieza = pz.numpieza))

En AR ((PRECIOSUM [numvend, numpieza] ÷ PIEZA[numpieza]) ∞ VENDEDOR) [nomvend] En CRT { V.nomvend / VENDEDOR(V) ∧ ∀P (PIEZA(P) ⇒ ∃ PR (PRECIOSUM(PR) ∧ PR.numvend=V.numvend ∧ PR.numpieza=P.numpieza ))}

--2 select nomvend from vendedor where numvend not in (select numvend from preciosum) order by nomvend --2 select nomvend from vendedor v where not exists (select * from preciosum where numvend = v.numvend) order by nomvend

En AR ((VENDEDOR[numvend] ∼ PRECIOSUM[numvend]) ∞ VENDEDOR)[nomvend] En CRT {V.nomvend / VENDEDOR(V) ∧ ⎤ ∃ PR(PRECIOSUM(PR) ∧ PR.numvend=V.numvend)}

--3 select numpieza, nompieza from pieza pz where not exists (select * from pedido pd where numvend=1 and not exists (select * from linped l where pd.numpedido=l.numpedido and pz.numpieza=l.numpieza))

En AR ((LINPED [numpieza, numpedido] ÷ (PEDIDO donde numvend=1)[numpedido]) ∞ PIEZA) [numpieza, nompieza] En CRT { P.numpieza, P.nompieza / PIEZA(P) ∧ ∀PD (PEDIDO(PD) ∧ PD.numvend=1 ⇒ ∃ LP (LINPED(LP) ∧ LP.numpedido=PD.numpedido ∧ LP.numpieza=P.numpieza ))}

--4 select distinct nombrecomer from vendedor v where not exists (select * from vendedor where nombrecomer = v.nombrecomer and provincia not in ('ALICANTE','CASTELLON','VALENCIA')) order by nombrecomer

En AR VENDEDOR[nombrecomer] ∼ (VENDEDOR donde provincia<>ALICANTE or provincia<>CASTELLON or provincia<>VALENCIA)[nombrecomer] En CRT { V.nombrecomer / VENDEDOR(V) ∧ ∀ V2 (VENDEDOR(V2) ∧ V2.nombrecomer=V.nombrecomer ⇒ (V2.provincia=ALICANTE ∨ V2.provincia=CASTELLON ∨ V2.provincia=VALENCIA))} O bien { V.nombrecomer / VENDEDOR(V) ∧ ⎤ ∃ V2 (VENDEDOR(V2) ∧ V2.nombrecomer=V.nombrecomer ∧ V2.provincia<>ALICANTE ∧ V2.provincia<>CASTELLON ∧ V2.provincia<>VALENCIA))}

Page 108: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior
Page 109: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

109

SOLUCIONES ADICIONALES 1 --3 select distinct numvend from preciosum ps, pieza p, linped l where ps.numpieza = p.numpieza and p.numpieza = l.numpieza and preciovent between 50 and 100 order by numvend

En AR PIEZA ∞ PRECIOSUM ∞ LINPED donde preciovent≥50 and preciovent≤100 [numvend] En CRT {PR.numvend / PRECIOSUM(PR) ∧ ∃ P (PIEZA(P) ∧ P.numpieza=PR.numpieza ∧ preciovent≥5000 ∧ preciovent≤10000 ∧ ∃ LP (LINPED(LP) ∧ PR.numpieza=LP.numpieza)) }

--4 select nombrecomer from vendedor v, pedido pd, linped l, pieza p where v.numvend = pd.numvend and pd.numpedido = l.numpedido and l.numpieza = p.numpieza and nompieza like '%MONITOR%' and provincia = 'ALICANTE' --5 select nompieza, p.numpieza from pieza p, linped l where p.numpieza = l.numpieza order by nompieza

En AR PIEZA ∞ LINPED [numpieza, nompieza] En CRT {P.numpieza, P.nompieza / PIEZA(P) ∧ ∃ LP (LINPED(LP) ∧ P.numpieza=LP.numpieza) }

--6 select ps.numpieza, preciounit - preciocompra from linped l, pedido pd, preciosum ps where l.numpedido = pd.numpedido and pd.numvend = ps.numvend and ps.numpieza = l.numpieza order by diferencia

En AR PRECIOSUM ∞ PEDIDO ∞ LINPED [numpieza, preciounit, preciocompra] En CRT {PR.numpieza, PR.preciounit, LP.preciocompra / PRECIOSUM(PR) ∧ LINPED(LP) ∧ ∃ P (PEDIDO(P) ∧ PR.numvend=P.numvend ∧ P.numpedido=LP.numpedido ∧ PR.numpieza=LP.numpieza) } En AR y C.R.T.: no está considerada, en la formalización de estos lenguajes, la resta como resultado.

--7 select distinct v.numvend, nombrecomer from vendedor v, pedido pd, linped l, preciosum ps where ps.numvend = v.numvend and v.numvend = pd.numvend and pd.numpedido = l.numpedido and l.numpieza = ps.numpieza and preciocompra > preciounit

En AR VENDEDOR ∞ PRECIOSUM ∞ PEDIDO ∞ LINPED donde preciocompra > preciounit [numvend, nomvend] En CRT {V.numvend, V.nomvend / VENDEDOR(V) ∧ ∃ PR(PRECIOSUM(PR) ∧ V.numvend=PR.numvend ∧ ∃ P (PEDIDO(P) ∧ PR.numvend=P.numvend ∧ ∃ LP(LINPED(LP) ∧ P.numpedido=LP.numpedido ∧ PR.numpieza=LP.numpieza ∧ preciocompra > p

Page 110: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

110

SOLUCIONES ADICIONALES 2 --1 select nomvend,count(*) cantidad from preciosum ps, vendedor v where ps.numvend=v.numvend group by v.numvend,nomvend order by nomvend --2 select v.numvend,nomvend,count(*) cantidad from preciosum ps, vendedor v where ps.numvend=v.numvend group by v.numvend,nomvend order by nomvend --6 select numvend, nomvend from vendedor v, pedido p, linped lp where v.numvend = p.numvend and p.numpedido = lp.numpedido group by p.numpedido,v.numvend, nomvend having count(distinct numpieza)> 3

En AR Define alias LP1, LP2, LP3 para LINPED LP1 × LP2 × LP3 × LINPED donde LP1.numpedido=LP2.numpedido and LP2.numpedido=LP3.numpedido and LP3.numpedido=LINPED.numpedido and LP1.numpieza<>LP2.numpieza and LP1.numpieza<> LP3.numpieza and LP1.numpieza<> LINPED.numpieza and LP2.numpieza<> LP3.numpieza and LP2.numpieza<>LINPED.numpieza and LP3.numpieza<> LINPED.numpieza [LP1.numpedido] ∞ PEDIDO ∞ VENDEDOR [numvend, nomvend] En CRT {V.numvend, V.nomvend / VENDEDOR(V) ∧ ∃ P (PEDIDO(P) ∧ P.numvend=V.numvend) ∧ ∃ LP1 ( LINPED(LP1) ∧ LP1.numpedido=P.numpedido ∧ ∃ LP2 (LINPED(LP2) ∧ LP1.numpedido=LP2.numpedido ∧ ∧ LP1.numpieza<>LP2.numpieza ∧ ∃ LP3 (LINPED(LP3) ∧ LP2.numpedido=LP3.numpedido ∧ LP1.numpieza<>LP3.numpieza ∧ LP2.numpieza<>LP3.numpieza ∧ ∃ LP4 (LINPED(LP4) ∧ LP3.numpedido=LP4.numpedido ∧ LP1.numpieza<>LP4.numpieza ∧ LP2.numpieza<>LP4.numpieza ∧ LP3.numpieza<>LP4.numpieza))))) }

--4 select p.numpedido, count(*), p.numvend, nomvend, fecha from pedido p, linped l, vendedor v where p.numvend = v.numvend and p.numpedido = l.numpedido group by p.numpedido, p.numvend, nomvend, fecha

(en este caso coincide count(*) y count(distinct numlinea) --7 select v.numvend, nomvend from vendedor v, pedido p where v.numvend = p.numvend --8 select nompieza, avg(preciosum), preciovent from preciosum ps, pieza p where p.numpieza = ps.numpieza group by nompieza, preciovent having avg(preciosum) > 100 and count(*) > 2

(aquí también coincide count(*) y count(distinct numvend) --9 select nompieza, avg(preciounit) media, preciovent from preciosum ps, pieza p where ps.numpieza=p.numpieza and preciovent > 30000 group by p.numpieza,nompieza,preciovent having count(*)>2 and avg(preciounit) between 100 and 280 order by p.nompieza --10 select p.numpieza, nompieza from pieza p, preciosum ps where p.numpieza = ps.numpieza group by p.numpieza, nompieza, preciovent having preciovent*20/100 > avg(preciounit)

(necesito poner el preciovent en el group by porque es no calculado)

Page 111: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

111

SOLUCIONES ADICIONALES 3 --1 select v.numvend, nomvend, count(*) cantidadPED from vendedor v, pedido p where v.numvend=p.numvend and provincia=’ALICANTE’ group by v.numvend, nomvend

--4 select p.numpieza, nompieza, max(preciounit) maxPrecio, min(preciounit) minPrecio, count(*) totalVend from preciosum ps, pieza p where ps.numpieza=p.numpieza group by p.numpieza, nompieza having avg(preciounit)<10 --5 select p.numpedido, v.numvend, nomvend, count(distinct fecharecep) from vendedor v, pedido p, linped lp where v.numvend = p.numvend and p.numpedido = lp.numpedido group by p.numpedido, v.numvend, nomvend having count(distinct fecharecep)> 1 --7 select p.numpieza, nompieza, v.numvend, nomvend from pieza p, linped lp , pedido ped, vendedor v where lp.numpieza=p.numpieza and lp.numpedido=ped.numpedido and ped.numvend=v.numvend and to_char(fecharecep, ‘d’)=7 order by 2

SOLUCIONES ADICIONALES 4 --1 select v.numvend, nomvend from pedido p, vendedor v where p.numvend=v.numvend and to_char(fecha,‘yyyy’)=1995 minus select v.numvend, nomvend from pedido p, vendedor v where p.numvend=v.numvend and to_char(fecha,‘yyyy’)=1992 --4 select numpieza, nompieza from pieza minus select p.numpieza, nompieza from linped lp, pieza p where lp.numpieza=p.numpieza

En AR PIEZA[numpieza, nompieza] ∼ (PIEZA ∞ LINPED)[numpieza, nompieza] En CRT {P.numpieza, P.nompieza / PIEZA(P) ∧ ⎤ ∃ LP(LINPED(LP) ∧ LP.numpieza=P.numpieza}

Page 112: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

112

--5 select numvend from preciosum ps, linped lp where ps.numpieza=lp.numpieza and numpedido=1 and numlinea=1 intersect select numvend from preciosum ps, linped lp where ps.numpieza=lp.numpieza and numpedido=1 and numlinea=2 intersect select numvend from preciosum ps, linped lp where ps.numpieza=lp.numpieza and numpedido=1 and numlinea=3

En AR Define alias V1, V2 para VENDEDOR PRECIOSUM [numvend, numpieza] ÷ LINPED DONDE (numpedido=1 and (numlinea=1 or numlinea=2 or numlinea=3)) [numpieza] En CRT {V.numvend / VENDEDOR(V) ∧ ∀ LP (LINPED(LP) ∧ LP.numpedido=1 ∧ (LP.numlinea=1 ∨ LP.numlinea=2 ∨ LP.numlinea=3) ⇒ ∃ PS(PRECIOSUM(PS) ∧ PS.numpieza=LP.numpieza ∧ PS.numvend=V.numvend) ) }

--6 select v.numvend, nomvend, sum(cantrecibida*preciocompra) Total from vendedor v, pedido p, linped lp where v.numvend=p.numvend and p.numpedido=lp.numpedido and provincia I (‘ALICANTE’, ‘MADRID’) group by v.numvend, nomvend

SOLUCIONES ADICIONALES 5 --1 select p.numpedido, v.numvend, nomvend, fecha from pedido p, linped lp, vendedor v where p.numvend=v.numvend and p.numpedido=lp.numpedido group by p.numpedido, fecha, v.numvend, nomvend having sum(ctdpedida*preciocompra) between 400 and 600

--4 select v.numvend, nomvend, p.numpieza, nompieza, count(distinct numpedido) from vendedor v, preciosum ps, pedido pd, linped lp, pieza p where v.numvend = pd.numvend and v.numvend=ps.numvend and pd.numpedido = lp.numpedido and p.numpieza=lp.numpieza and p.numpieza=ps.numpieza and diassum>7 group by v.numvend, nomvend, p.numpieza, nompieza order by 5 --5 select nombrecomer from vendedor group by nombrecomer having count(*)>3 intersect select nombrecomer from vendedor where provincia=’AICANTE’ group by nombrecomer having count(*)>1 --6 select nomvend, nombrecomer from vendedor where provincia not in (‘ALICANTE’,’CASTELLON’,’VALENCIA’) and telefono is null

Page 113: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

113

SOLUCIONES ADICIONALES 6 --2 select nomvend, avg(preciounit) mediasumin from vendedor v, preciosum ps where v.numvend=ps.numvend and ciudad IN (select ciudad from vendedor where nomvend like '%GARCIA%') group by v.numvend, nomvend,ciudad order by mediasumin --7 select numpedido, v.numvend, nomvend, fecha from pedido p, vendedor v where p.numvend=v.numvend and to_char(fecha,'YYYY')>1992 and numpedido in (select numpedido from linped group by numpedido having sum(preciocompra*cantrecibida) > any (select sum(preciocompra*cantrecibida) from linped group by numpedido)) --10 select ps.numpieza, nompieza, avg(preciounit) media, max(descuento) descuento from preciosum ps, pieza pz, vendedor v where ps.numpieza=pz.numpieza and v.numvend=ps.numvend and v.ciudad in (select ciudad from vendedor where nombrecomer='MECEMSA') and ps.numpieza in (select numpieza from linped group by numpieza having count(*)>1) group by ps.numpieza,nompieza order by ps.numpieza

SOLUCIONES ADICIONALES 7 --1 select v.numvend, nomvend from vendedor v, preciosum ps where v.numvend=ps.numvend and numpieza IN (select numpieza from preciosum where numvend=1) and numvend NOT IN ( select v.numvend, nomvend from vendedor v, preciosum ps where v.numvend=ps.numvend and numpieza IN (select numpieza from preciosum where numvend=2))

Page 114: Bases de Datos 1 - rua.ua.es¡ctica.pdf · Para realizar consultas sobre una base de datos vamos a utilizar la orden SELECT de SQL. Con la sintaxis que se muestra en el punto anterior

114

--1 select numvend, nomvend from vendedor where numvend IN (

select numvend from preciosum where numpieza IN (select numpieza from preciosum where numvend=1) MINUS select numvend from preciosum where numpieza IN (select numpieza from preciosum where numvend=2))

En AR (PRECIOSUM donde numvend=1 [numpieza] ∞ PRECIOSUM ∞ VENDEDOR)[numvend, nomvend] ∼ (PRECIOSUM donde numvend=2 [numpieza] ∞ PRECIOSUM ∞ VENDEDOR)[numvend, nomvend] En CRT {V1.numvend, V1.nomvend / VENDEDOR(V1) ∧ ∃ PS1(PRECIOSUM(PS1) ∧ PS1.numvend=V1.numvend ∧ ∃ PS2(PRECIOSUM(PS2) ∧ PS2.numvend=1 ∧ PS1.numpieza=PS2.numpieza ∧ ⎤ ∃ PS3(PRECIOSUM(PS3) ∧ PS3.numvend=V1.numvend ∧ ∃ PS4(PRECIOSUM(PS4) ∧ PS4.numvend=2 ∧ PS3.numpieza=PS4.numpieza)) ) ) }

--3 select v.numvend, nomvend, avg(preciocompra-preciounit) DifMedia from preciosum ps, pedido p, linped lp, vendedor v where p.numpedido=lp.numpedido and ps.numvend=p.numvend and lp.numpieza=ps.numpieza and p.numvend=v.numvend group by v.numvend, nomvend having max(precicompra-preciounit) = (Select max(preciocompra–preciounit) from preciosum ps, pedido p, linped lp where p.numpedido=lp.numpedido and ps.numvend=p.numvend and lp.numpieza=ps.numpieza) --4 select numpieza from pieza p, linped lp where p.numpieza=lp.numpieza and nompieza like ‘%TECLADO%’ and to_char(fecharecep, ‘mm’)=5 --6 select v.numvend, nomvend from vendedor v, pedido p, linped lp where v.numvend=p.numvend and p.numpedido=lp.numpedido group by v.numvend, nomvend having count(distinct numpieza)>3