Está en la página 1de 8

Gua de ejercicios de SQL

Prof. Claudio Gutirrez, Aux. Mauricio Monsalve

Otoo de 2008

[P1] Corretaje de propiedades


Enunciado Sean las siguientes tablas de una base de datos de una corredora de propiedades:

Arrendatario(RUT,Nombre,Apellido)
Arrienda(RUT,Id_casa,Deuda)Ojo:Deuda>=0(sies0,nohaydeuda)
Telefonos(RUT,Fono)
Dueo(RUT,Nombre,Apellido)
Casa(Id_casa,RUT,Nro,Calle,Comuna)

Al respecto, conteste las siguientes preguntas:


1. Los arrendatarios que arriendan la casa ubicada en la calle Carrera n 1024, Santiago.
2. Cunto le deben a Mara Prez?
3. Cul es la deuda total para cada dueo?
4. Liste todas las personas de la base de datos
5. Indique los dueos que poseen tres o ms casas.
6. Liste los dueos que tengan deudores en todas sus casas.
7. Entregue estadsticas sobre los arrendatarios por casa. Entregue:
1. El promedio.
2. La varianza.
3. El mximo.
4. El mnimo.
5. La moda.
6. La mediana.

Solucin Recomendacin: evite colocar selects en el from. Prefiera no anidar de esa manera;
muchas veces eso se puede escribir dentro de where.

1
1. Este es el tipo ms sencillo de consulta posible.

SELECTA.RUT,A.Nombre,A.Apellido
FROMArrendatarioA,ArriendaB,CasaC
WHEREA.RUT=B.RUTANDB.Id_casa=C.Id_casa
ANDC.Calle='Carrera'ANDC.Nro='1024'ANDC.Comuna='Santiago';

2. Se supondr que Mara Prez hay una sola.

SELECTSUM(A.Deuda)FROMArriendaA,CasaB,DueoC
WHEREA.Id_casa=B.Id_casaANDB.RUT=C.RUT
ANDC.Nombre='Mara'ANDC.Apellido='Prez';

3. Aqu es necesario agrupar la informacin, as la suma se har dentro de cada grupo indica-
do. Entregu toda la informacin necesaria en el SELECT, aunque con el RUT del dueo basta-
ra (si en el trabajo le piden algo as, entregue todo).

SELECTSUM(A.Deuda),C.RUT,C.Nombre,C.Apellido
FROMArriendaA,CasaB,DueoC
WHEREA.Id_casa=B.Id_casaANDB.RUT=C.RUT
GROUPBYC.RUT;

4. Las personas de la BD son los arrendatarios y los dueos. Para entregar ambos, hay que rea-
lizar una unin. Nota: para realizar una unin, los esquemas deben ser compatibles (atributos
con mismo nombre y
dominio). Afortunadamente, ste es el caso.

SELECT*FROMArrendatarioUNIONSELECT*FROMDueo;

5. Hay dos maneras de hacer esto: con agregacin y sin sta. El caso sin agregacin (menos
evidente en general) consiste en hacer un join de tres tablas.

Sin agregacin:

SELECTA.RUT,A.Nombre,A.Apellido
FROMDueoA,CasaC1,CasaC2,CasaC3
WHEREA.RUT=C1.RUTANDC1.RUT=C2.RUTANDC2.RUT=C3.RUT
ANDC1.Id_casa<>C2.Id_casaANDC1.Id_casa<>C3.Id_casa
ANDC2.Id_casa<>C3.Id_casa;

2
Con agregacin: en este caso, es necesario utilizar HAVING. HAVING es el WHERE pero
para funciones agregadas. En el HAVING slo pueden aparecer funciones agregadas y cons-
tantes.

SELECTA.RUT,A.Nombre,A.Apellido
FROMDueoA,CasaC
WHEREA.RUT=C.RUT
GROUPBYA.RUT
HAVINGCOUNT(DISTINCTC.Id_casa)>=3;

6. Jugando con la semntica vemos que un dueo con deudores en todas sus casas equivale a
un dueo con deuda en todas sus casas. Y el complemento de eso son los dueos con casas sin
deudas.

SELECTD.RUT,D.Nombre,D.Apellido
FROMDueoD,CasaC
WHERED.RUT=C.RUT
EXCEPT
SELECTD.RUT,D.Nombre,D.Apellido
FROMDueoD,CasaC,ArriendaA
WHERED.RUT=C.RUTANDC.Id_casa=A.Id_casaANDA.Deuda>0

Otra manera consiste en exigir que la deuda de cada casa del dueo sea positiva. En este caso,
una consulta
anidada exigiendo igualdad sobre ALL basta.

SELECTD.RUT,D.Nombre,D.Apellido
FROMDueoD,CasaC
WHERED.RUT=C.RUT
AND0=ALL( SELECTA.Deuda
FROMArriendaA
WHEREC.Id_casa=A.Id_casa)
ORNOTEXISTS( SELECT*
FROMArriendaA
WHEREC.Id_casa=A.Id_casa);

Esto es equivalente a lo anterior: que no exista (NOT EXISTS) una casa con deuda para este
dueo. De hecho, es ms eficiente.

SELECTD.RUT,D.Nombre,D.Apellido
FROMDueoD,CasaC
WHERED.RUT=C.RUT

3
ANDNOTEXISTS( SELECT*
FROMArriendaA
WHEREC.Id_casa=A.Id_casaANDA.Deuda>0);

7. En esta seccin veremos cmo calcular estadsticas con SQL estndar. El promedio de arren-
datarios por casa: la manera correcta de hacerlo es considerar todos los arrendatarios que efec-
tivamente arrienden y todas las casas. As se contarn las casas con 0 arrendatarios, que debe-
ran ser consideras en el promedio.

SELECTDISTINCTCOUNT(DISTINCTA.RUT)/COUNT(DISTINCTB.Id_casa)
FROMArriendaA,CasaB;

El mximo requiere una consulta anidada sencilla. Hay que contar el nmero de arrendatarios
por cada grupo y exigir que sea mayor a los de los dems grupos. Esta consulta tiene un error.
Cul es?1 Cmo se corrige?

SELECTCOUNT(A.RUT)
FROMArriendaA
GROUPBYA.Id_casa
HAVINGCOUNT(A.RUT)>=ALL( SELECTCOUNT(B.RUT)
FROMArriendaB
GROUPBYB.Id_casa);

El mnimo es anlogo. Esta consulta tiene un error. Cul es? Cmo se corrige?

SELECTCOUNT(A.RUT)
FROMArriendaA
GROUPBYA.Id_casa
HAVINGCOUNT(A.RUT)<=ALL( SELECTCOUNT(B.RUT)
FROMArriendaB
GROUPBYB.Id_casa);

Ahora necesito la siguiente consulta: el nmero de arrendatarios por casa. Se advierte que la
prctica de realizar consultas anidadas en el FROM se debe evitar si se puede usar IN, NOT IN,
EXISTS, ALL, etc.

(*)= SELECTId_casaASID,COUNT(DISTINCTRUT)ASN
FROMArrienda
GROUPBYId_casa

1 Hint: puede que el error est cerca del operador de agregacin...

4
UNION
SELECTId_casaASID,0ASN
FROMCasa
WHEREId_casaNOTIN( SELECTX.Id_casa
FROMArriendaX);

La varianza es la desviacin de la media. Puesto que dos operaciones agregadas son necesarias
para resolver esto, forzosamente necesitamos realizar una consulta previa e incluirla en el
FROM.
Frmula: Var[X]=E[X2]E2[X]

SELECTSUM(N*N)/COUNT(ID)AVG(N)*AVG(N)
FROM(*);

La moda es la frecuencia ms repetida. La frecuencia es el COUNT, por ende aplico la compa-


racin en el HAVING.

SELECTX.N
FROM(*)X
GROUPBYX.N
HAVINGCOUNT(DISTINCTX.ID)>=ALL( SELECTCOUNT(DISTINCTY.ID)
FROM(*)Y
GROUPBYY.N);

La mediana es la frecuencia central. Se supondr que es nica.

SELECTDISTICTX.N
FROM(*)X,(*)Y,(*)Z
WHEREX.N>Y.NANDX.N<Z.N
GROUPBYX.N
HAVINGCOUNT(DISTINCTY.ID)=COUNT(DISTINCTZ.ID);

Propuesto: Cmo se puede hacer en los casos con, por ejemplo, 4 candidatos? Algo como: 0 0
0 0 1 2 3 3 4 4 4 4 5 5 6 7 8 9 9 11. No es mucho ms complicado que la consulta anterior puesto
que hay que hacer una pequea observacin para contestar la pregunta.

5
[P2] Sistema de e-learning
Enunciado Noob Saiborg2 est desarrollando un sistema de evaluacin automtico como par-
te de un paquete de e-learning comercial. En este sistema, los tests consisten de 1 ms pre-
guntas con alternativas. Para hacer el sistema flexible, y para aumentar la dificultad de los pro-
blemas, uno de los requerimientos es que las preguntas -de las que consisten los tests- tengan
una o ms soluciones. (Por ejemplo, una pregunta del tipo Cul de las siguientes propiedades
presenta el paradigma OOP? requiere la seleccin de varias alternativas.) Actualmente, Noob
S. cuenta con el siguiente modelo de datos relacional para modelar los tests:

test(tnum,titulo,curso,descripcion,autor)
preg(tnum,pnum,enunciado)
pregalt(tnum,pnum,alt,texto,correcta)//correctaesbooleana
resp(user,tnum,pnum,alt)
alumno(user,nombre,apellido)
cursa(user,curso)
contesta(user,tnum)
cursos(curso,nombre)

En este sencillo (primitivo) modelo de datos, Noob S. necesita resolver los siguientes problemas
con SQL:
1. Sobrescribir el test X con otro test Y. (X,Y son tnum)
2. Conocer el nmero de tests por curso.
3. Conocer los cursos sin tests.
4. Determinar los tests con falencias. Un test tiene falencias si no tiene preguntas, si su
primera pregunta (pnum) no est numerada 1, si las preguntas no son consecutivas (ej.
1,2,4,5,8), si hay preguntas con 1 menos alternativas3, si todas las alternativas son
verdaderas o si todas las alternativas son falsas.
5. Corregir los test cuya nica falencia radica en la numeracin de las preguntas.
6. Cuntos alumnos hay en cada curso.
7. Qu alumnos han contestado tests que no les corresponden (de cursos que no cursan).
8. Obtener el puntaje no normalizado de cada rendicin de test. El puntaje no normaliza-
do ha sido definido (requerimiento) como: P = buenas malas/4. Si un alumno no con-
testa en una pregunta exactamente lo mismo que se ha definido como correcto, la pre-
gunta cuenta como mala a menos que el alumno haya omitido.
9. Obtener el puntaje normalizado, o sea, de 1,0 a 7,0.

Solucin Para resolver este problema es necesario saber cmo escribir consultas y cmo mo-
dificar datos con SQL.
2 Chiste fome MK2. Noob Saibot = Boon Tobias.
3 Esto es semnticamente incorrecto. Una seleccin mltiple es, en s misma, una alternativa. Pero en general se
entiende que una opcin y una alternativa son lo mismo. (Opcin es el trmino correcto.)

6
[1] Sobrescribir el test X con el test Y se hace borrando el test X y copiando los datos del test Y
con el tnum X. Haremos el proceso completo de borrado de un test, considerando si el test fue
contestado, y copiaremos los datos de Y.

deletefromtestwheretnum=X;
deletefrompregwheretnum=X;
deletefromaltwheretnum=X;
deletefromcontestawheretnum=X;
deletefromrespwheretnum=X;
insertintotestselectX,titulo,curso,descripcion,autor
fromtestwheretnum=Y;
insertintopregselectX,pnum,enunciado
frompregwheretnum=Y;
insertintopregaltselectX,pnum,alt,texto,correcta
frompregaltwheretnum=Y;

[2] El nmero de tests por curso tiene la forma (curso, nmero). Es una simple y vil agrupacin
con count(*).

selectcurso,count(*)
fromtest
groupbycurso;

[3] Una simple sustraccin.

selectcursofromcursos
except
selectcursofromtest;

[4] Cada exigencia del enunciado puede ser consultada por separado y luego unida para obte-
ner los tnum que corresponden a tests invlidos.

(
selecttnumfromtest
EXCEPTselecttnumfrompreg
)
UNION
(
selecttnumfrompreg
groupbytnumhavingmin(pnum)<1
)

7
UNION
(
selecttnumfrompreg
groupbytnumhavingmax(pnum)<>count(pnum)
)
UNION
(
selecttnumfrompregalt
groupbytnum,pnumhavingcount(alt)=1
)
UNION
(
selecttnumfrom(selecttnum,pregfrompreg
EXCEPTselecttnum,pregfrompregalt)
)
UNION
(
selecttnumfrompregalt
groupbytnum,althavingcount(distinctcierta)=1
);

El resto de las preguntas se dejan como ejercicios propuestos.

También podría gustarte