SQL - Query SQL

 
Vista:

Query SQL

Publicado por Ariel (8 intervenciones) el 05/07/2013 21:21:11
Hola! como estan? Estoy practicando un poco de SQL para rendir un examen y ante uno de los ejercicios me surgió una duda.
Teniendo este esquema
Estudiante(Id, e_nombre, e_carrera, año, edad) necesito consultar para cada valor de Edad, el valor de año que aparece mas frecuentemente.

Por ejemplo:

ID E_NOMBRE E_CARRERA ANIO EDAD
1 Juan Informatica 2 20
2 Arturo Informatica 2 21
3 Marcos Informatica 3 22
4 Penelope Informatica 2 20
5 Matias Informatica 2 19
6 Humberto Informatica 3 21
7 Ruperto Informatica 3 22
8 Enrique Electronica 1 20
9 Gabriel Informatica 3 20
10 Marianela Informatica 2 20

La sentencia en SQL que hice es la siguiente:

SELECT e.edad, e.anio
FROM Estudiante e
GROUP BY e.edad, e.anio
HAVING count(e.anio) >= ALL(SELECT count(distinct e1.anio)
FROM Estudiante e1
WHERE e1.edad = e.edad)

y el resultado:

EDAD ANIO
19 2
20 2
22 3

El problema es para la edad de 21 años, que se encuentra tanto en 2do año como en 3ro y que aparece una sola vez para ambas edades, no me aparece en el resultado, estaria esperando algo por el estilo:

EDAD ANIO
19 2
20 2
21 2
21 3
22 3

Alguna sugerencia? Muchas gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 806
Bronce
Ha mantenido su posición en SQL (en relación al último mes)
Gráfica de SQL

Query SQL

Publicado por leonardo_josue (1173 intervenciones) el 05/07/2013 22:21:24
Hola Ariel...

En realidad tienes varias formas para resolver esta consulta... vayamos por partes, en primer lugar, para obtener el valor que más se repite para cada año ocupas hacer dos cosas, en primer lugar CONTAR los casos y en segundo lugar obtener el MAXIMO de esos casos... para eso lo puedes hacer así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
mysql> SELECT * FROM tabla;
+------+-----------+-------------+------+------+
| ID   | E_NOMBRE  | E_CARRERA   | ANIO | EDAD |
+------+-----------+-------------+------+------+
|    1 | Juan      | Informatica |    2 |   20 |
|    2 | Arturo    | Informatica |    2 |   21 |
|    3 | Marcos    | Informatica |    3 |   22 |
|    4 | Penelope  | Informatica |    2 |   20 |
|    5 | Matias    | Informatica |    2 |   19 |
|    6 | Humberto  | Informatica |    3 |   21 |
|    7 | Ruperto   | Informatica |    3 |   22 |
|    8 | Enrique   | Electronica |    1 |   20 |
|    9 | Gabriel   | Informatica |    3 |   20 |
|   10 | Marianela | Informatica |    2 |   20 |
+------+-----------+-------------+------+------+
10 rows in set (0.00 sec)
 
mysql> SELECT edad, MAX(total) max_total FROM
    ->    (  SELECT anio, edad, COUNT(*) total
    ->       FROM tabla
    ->       GROUP BY anio, edad
    ->     ) T2 GROUP BY edad ;
+------+-----------+
| edad | max_total |
+------+-----------+
|   19 |         1 |
|   20 |         3 |
|   21 |         1 |
|   22 |         2 |
+------+-----------+
4 rows in set (0.00 sec)


Esta consulta te dice el mayor numero de casos que tiene cada edad... ahora bien, con la consulta interna (la que tiene el COUNT()) obtienes el número de casos que tiene cada año y edad, es decir, algo como esto:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> SELECT anio, edad, COUNT(*) total
    ->    FROM tabla
    ->    GROUP BY anio, edad;
+------+------+-------+
| anio | edad | total |
+------+------+-------+
|    1 |   20 |     1 |
|    2 |   19 |     1 |
|    2 |   20 |     3 |
|    2 |   21 |     1 |
|    3 |   20 |     1 |
|    3 |   21 |     1 |
|    3 |   22 |     2 |
+------+------+-------+
7 rows in set (0.00 sec)


Entonces, lo que tienes que hacer es filtrar estos casos a partir de los resultados de la consulta anterior... es decir, traer todos los casos que tengan la misma edad y el mismo numero de casos que resultaron de la primer consulta... podrías hacerlo poniendo una cláusula HAVING COUNT(), como lo intentaste hacer en tu consulta, o simplemente haciendo un JOIN...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mysql> SELECT T1.edad, T1.anio FROM
    -> (  SELECT anio, edad, COUNT(*) total
    ->    FROM tabla
    ->    GROUP BY anio, edad
    -> ) T1
    -> INNER JOIN
    -> (  SELECT edad, MAX(total) max_total FROM
    ->    (  SELECT anio, edad, COUNT(*) total
    ->       FROM tabla
    ->       GROUP BY anio, edad
    ->     ) T2 GROUP BY edad
    -> ) T3 ON T1.edad = T3.edad AND T1.total = t3.max_total;
+------+------+
| edad | anio |
+------+------+
|   19 |    2 |
|   20 |    2 |
|   21 |    2 |
|   21 |    3 |
|   22 |    3 |
+------+------+
5 rows in set (0.00 sec)


Insisto, hay otras formas de resolver esta consulta, pero esas te tocan a ti para que sigas practicando.

Saludos
Leo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

Query SQL

Publicado por Ariel (8 intervenciones) el 05/07/2013 23:46:07
Muchas gracias, habia intentado hacer algo similar a tu respuesta al empezar, solo que tendria que hacerlo sin usar sub-queries en la sentencia FROM, ya que de resolverlo de esta manera en el examen no lo tenemos permitido. Ahi es donde me estoy trabando.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Query SQL

Publicado por Ariel (8 intervenciones) el 23/07/2013 04:58:14
Hola como estan? Vuelvo a escribir sobre este tema, me gustaria saber como puedo resolverlo dentro de la clausula HAVING, porque no me ha salido de esta manera. Muchas gracias!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Query SQL

Publicado por Ariel (8 intervenciones) el 23/07/2013 17:45:51
Lo pude resolver, de esta manera, era sencillo pero no me salía porque no entendía bien algunos conceptos teóricos. Saludos.

SELECT e.edad,e.anio
FROM Estudiante e
GROUP BY e.edad, e.anio
HAVING count(e.anio) >= ALL(SELECT count(e1.anio)
FROM ESTUDIANTE e1
WHERE e1.edad = e.edad
GROUP BY e1.edad, e1.anio)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar