Departamento de Lenguajes y Sistemas Informáticos E.T.S. Ingeniería Informática. Universidad de Sevilla Avda Reina Mercedes s/n. 41012 Sevilla Tlf/Fax 954 557 139 E-mail [email protected] Web www.lsi.us.es Bases de Datos Bases de Datos Práctica 7 WinRDBI Consultas en cálculo relacional y SQL Sevilla, abril 2009 V 2009.4.1 e.t.s. ingeniería informática Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 Indice 1 CÁLCULO RELACIONAL........................................................................................................................................................ 3 1.1 1.2 1.3 1.4 2 CÁLCULO RELACIONAL ORIENTADO A TUPLAS (CROT). ...................................................................................................... 4 EJERCICIOS EN CROT. ...................................................................................................................................................... 4 CÁLCULO RELACIONAL ORIENTADO A DOMINIOS (CROD). ................................................................................................. 5 EJERCICIOS EN CROD. ...................................................................................................................................................... 5 SQL............................................................................................................................................................................................. 6 2.1 2.1.1 2.1.2 2.1.3 2.1.4 2.2 DIFERENCIAS CON SQL ACCESS. ........................................................................................................................................ 6 Join. ..........................................................................................................................................................................................................................6 TOP n. .....................................................................................................................................................................................................................7 DISTINCT .............................................................................................................................................................................................................7 Consultas anidadas. ...............................................................................................................................................................................................7 EJERCICIOS EN SQL........................................................................................................................................................... 8 SOLUCIÓN CROT. ............................................................................................................................................................................. 9 SOLUCIÓN CROD............................................................................................................................................................................ 10 SOLUCIÓN SQL. ...............................................................................................................................................................................11 Pág. 2 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 1 Cálculo relacional Desde la opción ‘New Query’ del menú se selecciona el tipo de consulta. Consultas en CROT (.trc) Los nombres de variable (tuplas o dominios) deben empezar por una letra mayúscula. La equivalencia de escritura de los operadores lógicos y cuantificadores se indica en la siguiente tabla: Cálculo Relacional F∧G F∨ G ¬F F→G ∃x ( F ) WinRDBi F and G F or G not F not F or G (exists x)(F) ∃/x ( F ) not (exists x)(F) ∀x ( F ) (forall x)(F) Pág. 3 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 1.1 Cálculo relacional orientado a tuplas (CROT). Variable tupla A libre Variable tupla P libre Variable tupla A acotada 1.2 Ejercicios en CROT. Con la BD hobbies resolver las siguientes consultas: 1) Relación de hobbies 2) Lista de nombres de personas (Proyección) 3) Nombres de personas y sus aficiones (Join) 4) Personas a las que les gusta el Tenis 5) Personas a las que les gustan todos los hobbies 6) Personas a las que no les gusta nada Pág. 4 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 1.3 Cálculo relacional orientado a dominios (CROD). Se utilizará el CROD By-Name ya que el posicional obliga a conocer la posición de cada atributo en el esquema de la relación. Consultas en CROD (.dbn) Variable dominio Px libre Variable dominio Px libre Variable tupla Ix acotada 1.4 Ejercicios en CROD. Con la BD hobbies resolver las siguientes consultas: 1) Personas 2) Personas con idPersona igual a 2 3) Personas con idPersona mayor que 2 4) Personas a las que les gusta el cine 5) Personas a las que no les gusta ningún hobby 6) Personas a las que les gustan todos los hobbies Pág. 5 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 2 SQL Desde la opción ‘New Query’ del menú se selecciona SQL. 2.1 Diferencias con SQL Access. 2.1.1 Join. Hay dos formas de hacer el join en WinRDBi: a) Join natural Ej. SELECT persona, hobby FROM (personas NATURAL JOIN aficiones); b) Join natural RPC Ej. SELECT persona, hobby FROM personas P, aficiones A WHERE A.idPersona=P.idPersona; En Access, la consulta anterior sería: a) Join natural Ej. SELECT persona, hobby FROM (personas AS P JOIN aficiones AS A) ON (A.idPersona=P.idPersona); b) Join natural RPC (igual que WinRDBi) Ej. SELECT persona, hobby FROM personas P, aficiones A WHERE A.idPersona=P.idPersona; Pág. 6 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 2.1.2 TOP n. No está permitido en SQL WinRDBi 2.1.3 DISTINCT En Access no es posible utilizar la cláusula DISTINCT dentro de la función count( ), será necesario hacer SELECT FROM (SELECT.. ) Así por ej. la consulta contar el número de aficiones distintas (hobbies) que hay en la tabla de aficiones quedaría: a) En SQL WinRDBi: SELECT count(distinct hobby) FROM aficiones; b) En SQL Access: SELECT count(*)FROM (SELECT hobby FROM aficiones GROUP BY hobby) ; 2.1.4 Consultas anidadas. No están permitidas en SQL WinRDBi Así por ej. la consulta “persona con el máximo número de aficiones” se podría resolver en SQL Access de dos formas: a) SELECT TOP 1 persona, count(*) AS na FROM personas AS P INNER JOIN aficiones AS A ON A.idPersona=P.idPersona GROUP BY persona ORDER BY 2 DESC; b) SELECT persona AS na FROM personas AS P INNER JOIN aficiones AS A ON A.idPersona=P.idPersona GROUP BY persona HAVING count(*) = (SELECT MAX(na) FROM (SELECT persona, count(*) AS na FROM personas AS P INNER JOIN aficiones AS A ON A.idPersona=P.idPersona GROUP BY persona)); En SQL WinRDBI sería necesario hacerlo en varios pasos: cuentaAficionesDeCadaUno:=select persona,count(*) as na from (personas natural join aficiones) group by persona order by 2 desc; maximoAficiones:=select max(na) maxAf from cuentaAficionesDeCadaUno; campeon:=select persona from cuentaAficionesDeCadaUno where na = (select maxAf from maximoAficiones); Pág. 7 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 2.2 Ejercicios en SQL. Con la BD hobbies resolver las siguientes consultas: 1) Relación de hobbies 2) Aficiones de cada persona. Ejemplos de join 3) Personas a las que no les gusta ningún hobby 4) Personas a las que les gustan todos los hobbies 5) Personas aficionadas al Tenis 6) Número de aficiones 7) Número de aficiones distintas 8) Número de aficiones de cada uno 9) Número máximo de aficiones que tiene alguien 10) Persona con el número máximo de aficiones 11) Personas que tienen más de una afición Pág. 8 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 Solución CROT. % 1) Relación de hobbies qCROT1:={ H.hobby | hobbies(H)}; % 2) Lista de nombres de personas (Proyección) qCROT2:= { P.persona | personas(P)}; % 3) Nombres de personas y sus aficiones (Join) qCROT3:= { P.persona,A.hobby | personas(P) and aficiones(A) and A.idPersona = A.idPersona}; % 4) Personas a las que les gusta el Tenis qCROT4:= { P.persona,A.hobby | personas(P) and aficiones(A) and A.idPersona = A.idPersona and A.hobby='Tenis'}; % 5) Personas a las que les gustan todos los hobbies qCROT5_1:= { P.persona | personas(P) and (forall H)(not hobbies(H) or (exists A) ( aficiones(A) and A.hobby = H.hobby and P.idPersona = A.idPersona ) qCROT5_2:= { P.persona | personas(P) and not (exists H)( hobbies(H) and not (exists A) ( aficiones(A) and A.hobby = H.hobby and P.idPersona = A.idPersona ) ) }; ) }; % 6) Personas a las que no les gusta nada qCROT6:= { P.persona | personas(P) and not (exists A)( aficiones(A) and P.idPersona = A.idPersona ) }; Pág. 9 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 Solución CROD. % 1) Personas qCD1(person:Px)<-personas(persona:Px); % 2) Personas con idPersona igual a 2 qCD2(person:Px)<-personas(persona:Px , idPersona:2); % 3) Personas con idPersona mayor que 2 qCD3(person:Px)<-(exists Ix)(personas(persona:Px , idPersona:Ix) and Ix>2); % 4) Personas a las que les gusta el cine qCD4(person:Px)<-(exists Ix)(personas(persona:Px, idPersona:Ix ) and (aficiones(idPersona :Ix , hobby:'Cine'))); % 5) Personas a las que no les gusta ningún hobby qCD5(person:Px)<-(exists Ix)(personas(persona:Px, idPersona:Ix ) and not (aficiones(idPersona :Ix))); % 6) Personas a las que les gustan todos los hobby qCD6a(person:Px)<-(exists Ix)(personas(persona:Px, idPersona:Ix ) and (forall Hx)(not hobbies(hobby:Hx) or aficiones(idPersona :Ix, hobby:Hx))); qCD6b(person:Px)<-(exists Ix)(personas(persona:Px, idPersona:Ix ) and not (exists Hx)(hobbies(hobby:Hx) and not aficiones(idPersona :Ix, hobby:Hx))); Pág. 10 de 11 Bases de Datos. Práctica 7 WinRDBi Sevilla, Abril 2009, V 2009.4.1 Solución SQL. % 1) Relación de hobbies relacionHobbies:=select * from hobbies; % 2) Aficiones de cada persona. Ejemplos de join joinNatural:= select persona,hobby from (personas natural join aficiones); joinNaturalComoRPC:= select persona,hobby from personas P, aficiones A where A.idPersona=P.idPersona; % 3) Personas a las que no les gusta ningún hobby personasSINhobbies:=select persona from personas P where not exists (select * from aficiones A where A.idPersona=P.idPersona); % 4) Personas a las que les gustan todos los hobbies personasAqgustaTodo:= select P.persona from personas P where not exists (select * from hobbies H where not exists (select * from aficiones A where A.hobby = H.hobby and A.idPersona=P.idPersona)); % 5) Personas aficionadas al Tenis personasQgustaTenis_1:= select persona from personas P where exists (select * from aficiones A where A.idPersona = P.idPersona and A.hobby = 'Tenis'); personasQgustaTenis_2:= select persona from (personas natural join aficiones) where hobby = 'Tenis'; % 6) Número de aficiones cuentaAficiones:= select count(*) from aficiones; % 7) Número de aficiones distintas cuentaAficionesDist:= select count(distinct hobby) from aficiones; % 8) Número de aficiones de cada uno cuentaAficionesDeCadaUno:=select persona,count(*) as na from (personas natural join aficiones) group by persona order by 2 desc; % 9) Número máximo de aficiones que tiene alguien maximoAficiones:=select max(na) maxAf from cuentaAficionesDeCadaUno; % 10) Persona con el número máximo de aficiones campeon:=select persona from cuentaAficionesDeCadaUno where na = (select maxAf from maximoAficiones); % 11) Personas que tienen más de una afición quienTieneMasdeUnaAficion:=select persona,count(*) as na from (personas natural join aficiones) group by persona having count(*)>1; Pág. 11 de 11