Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Guia SQL
Guia SQL
3. Aqu es necesario agrupar la informacin, as la suma se har dentro de cada grupo indicado. Entregu toda la informacin necesaria en el SELECT, aunque con el RUT del dueo bastara (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 realizar 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;
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 constantes.
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
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 arrendatarios por casa: la manera correcta de hacerlo es considerar todos los arrendatarios que efectivamente arrienden y todas las casas. As se contarn las casas con 0 arrendatarios, que deberan 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...
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 comparacin en el HAVING.
SELECTX.N
FROM(*)X
GROUPBYX.N
HAVINGCOUNT(DISTINCTX.ID)>=ALL( SELECTCOUNT(DISTINCTY.ID)
FROM(*)Y
GROUPBYY.N);
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.
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 normalizado ha sido definido (requerimiento) como: P = buenas malas/4. Si un alumno no contesta en una pregunta exactamente lo mismo que se ha definido como correcto, la pregunta 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 modificar 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.)
[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;
[4] Cada exigencia del enunciado puede ser consultada por separado y luego unida para obtener los tnum que corresponden a tests invlidos.
(
selecttnumfromtest
EXCEPTselecttnumfrompreg
)
UNION
(
selecttnumfrompreg
groupbytnumhavingmin(pnum)<1
)
UNION
(
selecttnumfrompreg
groupbytnumhavingmax(pnum)<>count(pnum)
)
UNION
(
selecttnumfrompregalt
groupbytnum,pnumhavingcount(alt)=1
)
UNION
(
selecttnumfrom(selecttnum,pregfrompreg
EXCEPTselecttnum,pregfrompregalt)
)
UNION
(
selecttnumfrompregalt
groupbytnum,althavingcount(distinctcierta)=1
);