SQL - PROBLEMA CON OUTER

   
Vista:

PROBLEMA CON OUTER

Publicado por Paula (2 intervenciones) el 17/01/2014 14:12:05
Buenos días,

Estoy tratando de perfeccionar mis conocimientos en SQL, y estaba trabajando sobre la sentencia SELECT utilizando OUTER para realizar la cuenta de los registros asociados, y que si no hay, aparezca 0. Pero me surge un problema...

Si realizo esta consulta

select * from usuarios left outer join familias
on usuarios.iduser = familias.iduser

mis resultados son perfectos. Cada usuario tiene varias familias, así que aparecen los datos del usuario y a continuación de la familia, y si el usuario no tiene ninguna familia, pues esos campos aparecen a null.

Pero si la consulta realizada es:

select usuarios.iduser, count(familias.idfamilia) from usuarios left outer join familias
on usuarios.iduser = familias.iduser

Sólo me sale un usuario y un valor que no se corresponde con nada.


¿¿Alguien me puede dar alguna idea??

Adjunto enlace a imagen con las consultas (la primera la he limitado a las claves de cada tabla, para no publicar datos y direcciones). https://www.dropbox.com/sh/szsxwf1hkfuagd4/UDlbAY6pc4

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

PROBLEMA CON OUTER

Publicado por Paula (2 intervenciones) el 17/01/2014 16:08:56
Desconozco la razón, pero he encontrado la solución, si añadimos la sentencia GROUP BY, funciona:


select usuarios.iduser, count(familias.idfamilia) from usuarios left outer join familias
on usuarios.iduser = familias.iduser group by (usuarios.iduser)
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

PROBLEMA CON OUTER

Publicado por leonardo_josue (878 intervenciones) el 17/01/2014 16:29:39
Hola Paula...

El problema es que por lo que veo no sabes cómo trabajan las funciones de agrupación...

Tal como su nombre lo dice, las funciones de agrupación (COUNT, MIN, MAX, AVG) sirven para "agrupar" información que tiene UNO O MÁS CAMPOS EN COMÚN y haciendo GRUPOS... pero cuando se omite la cláusula GROUP BY, entonces el resultado se aplica con la agrupación de TODOS LOS REGISTROS... observa este script para ver si queda un poco más claro... supongamos que tenemos estas dos tablas:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
mysql> SELECT * FROM tabla1;
+------+-------------+
| id   | descripcion |
+------+-------------+
|    1 | uno         |
|    2 | dos         |
|    3 | tres        |
|    4 | cuatro      |
+------+-------------+
4 rows in set (0.00 sec)
 
mysql> SELECT * FROM tabla2;
+------+-------------+
| id   | descripcion |
+------+-------------+
|    1 | one         |
|    2 | two         |
|    2 | deux        |
|    4 | four        |
|    4 | Quatre      |
|    4 | Quattro     |
+------+-------------+
6 rows in set (0.00 sec)

Por un lado en la tabla1 tenemos los algunos números en español y en la tabla2 algunas traducciones, si hacemos un LEFT JOIN sobre las tablas, el resutlado sería el siguiente:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> SELECT * FROM tabla1
    -> LEFT JOIN tabla2 ON tabla1.id = tabla2.id
    -> ORDER BY tabla1.id;
+------+-------------+------+-------------+
| id   | descripcion | id   | descripcion |
+------+-------------+------+-------------+
|    1 | uno         |    1 | one         |
|    2 | dos         |    2 | deux        |
|    2 | dos         |    2 | two         |
|    3 | tres        | NULL | NULL        |
|    4 | cuatro      |    4 | Quattro     |
|    4 | cuatro      |    4 | Quatre      |
|    4 | cuatro      |    4 | four        |
+------+-------------+------+-------------+
7 rows in set (0.00 sec)


Aquí se observa que algunos números tienen más de una traducción, pero también hay números sin ninguna traducción...

Cuando aplicas un COUNT SIN ESPECIFICAR LA CLÁUSULA GROUP BY, lo que estás diciendo es simplemente que te diga CUANTOS REGISTROS TIENE TODA LA TABLA...

Si colocas DENTRO DEL COUNT un campo perteneciente a la tabla1, el resultado es contar cuantos registros distintos de null existen en esa columna... para este ejemplo 7:

1
2
3
4
5
6
7
8
9
mysql> SELECT COUNT(tabla1.id) FROM tabla1
    -> LEFT JOIN tabla2 ON tabla1.id = tabla2.id
    -> ORDER BY tabla1.id;
+------------------+
| COUNT(tabla1.id) |
+------------------+
|                7 |
+------------------+
1 row in set (0.00 sec)

Si dentro del count COLOCAS UN CAMPO DE LA tabla2, entonces igual, te cuenta cuantos campos distintos de null hay en esa columna, entonces el resultado es 6 (observa que el número tres no tiene una traducción)

1
2
3
4
5
6
7
8
9
mysql> SELECT count(tabla2.id) FROM tabla1
    -> LEFT JOIN tabla2 ON tabla1.id = tabla2.id
    -> ORDER BY tabla1.id;
+------------------+
| count(tabla2.id) |
+------------------+
|                6 |
+------------------+
1 row in set (0.00 sec)

Ahora bien, si lo que quieres es obtener CUANTAS TRADUCCIONES (o familias en tu caso) tiene cada número de la tabla1, ENTONCES TIENES QUE AGREGAR LA CLÁUSULA GROUP BY... de tal manera que AGRUPE CADA ID POR SEPARADO... en otras palabras que haga los COUNT de manera parcial, no total...

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> SELECT tabla1.id, COUNT(tabla2.id) FROM tabla1
    -> LEFT JOIN tabla2 ON tabla1.id = tabla2.id
    -> GROUP BY tabla1.id
    -> ORDER BY tabla1.id;
+------+------------------+
| id   | COUNT(tabla2.id) |
+------+------------------+
|    1 |                1 |
|    2 |                2 |
|    3 |                0 |
|    4 |                3 |
+------+------------------+
4 rows in set (0.00 sec)

Si sumas los totales "PARCIALES" (1+2+0+3) obtendrás el mismo resultado que en el COUNT ANTERIOR, es decir 6.

Espero que con este panorama te quede un poco más claro el por qué de la solución, y no solo te quedes con la respuesta sin analizar de fondo el problema

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
0
Comentar