UTNianos

Versión completa: [Gestión de Datos] [Aporte] Final 10/12/2013
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
El final del día de hoy (10/12/2013) fue el siguiente:

Verdadero o Falso
1a) Si existe un select dentro de una cláusula HAVING, este debe devolver 1 fila y 1 columna
1b) Gracias a los índices se puede asegurar la integridad referencial (o algo así)

Explicar en no más de 15 renglones
2a) Indices: concepto, funcionalidades y utilización.
2b) Indicar que hace que un DBMS sea transaccional

Práctica

3) Daban un DER:
[Imagen: Dibujo_sin_t_tulo_1.png]
Aclararon que en cada tabla, lo que está por encima de la línea divisoria corresponde a la PK, es decir t1_id es PK de T1, t1_id y t3_id son PK compuesta de T2, y t3_id es PK de T3

y la siguiente query relacionada:

SELECT T1.t1_id, (SELECT COUNT(distinct T2.t3_id) from T2 where T2.t1_id = T1.t1_id)
FROM T1

3a1) Pide reescribir la query pero sin subselects, y que devuelva el mismo resultado

3a2) ¿Como cambiaría el resultado de la consulta si se saca el "distinct" de la query?

3b) Dada la siguiente query, en caso de que tenga errores, detallar cada uno de ellos. Si no tuviera errores, ¿que podría hacer para optimizar la consulta siendo que la tabla T1 posee más de 1 millón de registros?

SELECT T1.t1_id, T1.t1_col2+T1.t1_col2, SUM(T2.t3_col2)
FROM T1, T2
WHERE T2.t1_id = T1.t1_id AND COUNT(*)>1
GROUP BY T1.t1_id
HAVING T1.t1_id IN (select T3.t3_id from T3 order by T3.t3_col2)


Dieron 5 minutos para revisarlo al comenzar, y luego 1 hora 15 minutos para resolverlo.

Saludos!
Parte práctica. Yo contestaría

3)a)
select t1.t1_id, COUNT( distinct t3.t3_id) from t1,t2,t3
where t1.t1_id=t2.t1_id and t3_id = t2.t3_id
group by t1.t1_id

3)b)
* No puede haber un order by dentro de una subconsulta.
* La condición count(*) del WHERE no es correcta (no actúa sobre varios registros)
* Hay valores que no estan en group by.
para optimizar la consulta eliminaría el uso de la subconsulta y aplicaría indices en los valores donde realiza join (id) para mejorar el acceso a los datos.
Agrego un error: T2.t3_col2, la columna no pertenece a esa tabla

Y en el where, el count esta mal por el solo hecho ya de no estar en una subconsulta, sin adentrarse en intentar adivinar qué se suponía que hacía jaj
Me dan una mano con esta?

1a) Si existe un select dentro de una cláusula HAVING, este debe devolver 1 fila y 1 columna

Dado el caso de que se pueda usar ANY/ALL/EXISTS/NOT EXISTS en el HAVING, ya sería falsa, pero no sé si se pude y no logro que se me ocurra un ejemplo para probar. Probé uno con ANY y no me compiló.
Si alguno tiene un link o archivo donde diga bien y completo que se puede hacer dentro de cada statement (where, having...) se agradece mucho!

Otra cosa, esto no está mal por dos motivos?
HAVING T1.t1_id IN (select T3.t3_id from T3 order by T3.t3_col2)
Primero me parece que tendría que ir en el WHERE, segundo, se puede usar el IN así? El IN no se usa así? campo1 IN (valor1,valor2,valor3) ? O funciona con un select también? En caso de que sí, compara contra cada registro devuelto por el select no? Tendría que devolver un solo campo por registro... no?
Yo creo que no es con IN sino con ANY: T1.t1 = ANY (select ..)

Saludos!

PD: En las subconsultas sí se pueden poner order by, al menos en SQL Server 2008, claro que siempre que hacia esto, mi select tenía un TOP 1 y devolvía además una sola columna. En la del ejemplo particularmente no se usa TOP así que puede ser que ahí rompa también por eso.
(13-12-2015 22:22)DarkCrazy escribió: [ -> ]Me dan una mano con esta?

1a) Si existe un select dentro de una cláusula HAVING, este debe devolver 1 fila y 1 columna

Dado el caso de que se pueda usar ANY/ALL/EXISTS/NOT EXISTS en el HAVING, ya sería falsa, pero no sé si se pude y no logro que se me ocurra un ejemplo para probar. Probé uno con ANY y no me compiló.
Si alguno tiene un link o archivo donde diga bien y completo que se puede hacer dentro de cada statement (where, having...) se agradece mucho!

Otra cosa, esto no está mal por dos motivos?
HAVING T1.t1_id IN (select T3.t3_id from T3 order by T3.t3_col2)
Primero me parece que tendría que ir en el WHERE, segundo, se puede usar el IN así? El IN no se usa así? campo1 IN (valor1,valor2,valor3) ? O funciona con un select también? En caso de que sí, compara contra cada registro devuelto por el select no? Tendría que devolver un solo campo por registro... no?
Yo creo que no es con IN sino con ANY: T1.t1 = ANY (select ..)

Saludos!

PD: En las subconsultas sí se pueden poner order by, al menos en SQL Server 2008, claro que siempre que hacia esto, mi select tenía un TOP 1 y devolvía además una sola columna. En la del ejemplo particularmente no se usa TOP así que puede ser que ahí rompa también por eso.


El IN se puede usar de esa manera, y también de la manera que vos detallas.
La de V o F es verdadero, ya que te deja usarlo el having de esa manera (aunque es poco feliz).
Ejecuté esta query y me devolvió resultados:

select cuil, sum(importe) from valores
group by cuil
having cuil in (99999999)

99999999 44071.18



La respuesta es SI, el IN con el select se fija si el campo seleccionado se encuentra en el select que se le detalla.
Tampoco te deja agregar el order by en subconsultas, ya que te arroja el siguiente error "La cláusula ORDER BY no es válida en vistas, funciones insertadas, tablas derivadas, subconsultas ni expresiones de tabla común, salvo que se especifique también TOP, OFFSET o FOR XML." (Esto es en SQL 2012)
La 1a es FALSO.

SELECT cuil
FROM valores
GROUP BY cuil
HAVING cuil IN (SELECT v2.cuil FROM valores v2 )

Eso funca, ya lo proba con valores.
URLs de referencia