Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

Liado con SELECT.... JOIN....

Estas en el tema de Liado con SELECT.... JOIN.... en el foro de Mysql en Foros del Web. Hola compañeros, llevo un rato intentando crear una consulta que no me acaba de devolver los datos como yo espero tenerlos, os explico: Tengo dos ...
  #1 (permalink)  
Antiguo 10/05/2009, 10:53
Avatar de DooBie  
Fecha de Ingreso: septiembre-2004
Mensajes: 1.101
Antigüedad: 19 años, 7 meses
Puntos: 71
Liado con SELECT.... JOIN....

Hola compañeros, llevo un rato intentando crear una consulta que no me acaba de devolver los datos como yo espero tenerlos, os explico:

Tengo dos tablas, una tbl_categorias(id, categoria) y otra tbl_productos(id, id_categoria, nombre)
El caso, es que quiero seleccionar todas las categorias de la tabla tbl_categorias junto al total de productos que tiene relacionadas con la tabla tbl_productos (el campo id_categoria es el id de la tbl_categorias, aunque las tablas son MyISAM)

Yo he probado con esto:

Código:
SELECT tbl_categorias.*, COUNT(tbl_productos.id) AS productos FROM tbl_categorias JOIN tbl_productos ON tbl_categorias.id = tbl_productos.id_categoria ORDER BY tbl_categorias.categoria ASC;
Con esta consulta, me devuelve un unico registro mas o menos asi:
Código:
id 	categoria 	productos
1 	cat_prueba 	132
Ni que decir, que tengo mas de una categoria y no todos los productos estan en la misma categoria!

La verdad que no se que mas probar, alguna sugerencia?
  #2 (permalink)  
Antiguo 10/05/2009, 11:36
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Liado con SELECT.... JOIN....

Código sql:
Ver original
  1. SELECT
  2.    c.categoria ,
  3.    COUNT(*) productos
  4. FROM tbl_categorias c JOIN tbl_productos p ON c.id = p.id_categoria
  5. ORDER BY c.categoria
  6. GROUP BY c.categoria;
El tema es que agrupe las categorías, sea por nombre o ID. Al hacerlo, se generan subtotales pro grupo.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 10/05/2009, 13:42
Avatar de DooBie  
Fecha de Ingreso: septiembre-2004
Mensajes: 1.101
Antigüedad: 19 años, 7 meses
Puntos: 71
Respuesta: Liado con SELECT.... JOIN....

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Código sql:
Ver original
  1. SELECT
  2.    c.categoria ,
  3.    COUNT(*) productos
  4. FROM tbl_categorias c JOIN tbl_productos p ON c.id = p.id_categoria
  5. ORDER BY c.categoria
  6. GROUP BY c.categoria;
El tema es que agrupe las categorías, sea por nombre o ID. Al hacerlo, se generan subtotales pro grupo.
Ya lo he conseguido, aunque en tu consulta habia un pequeño error, el GROUP BY va antes del ORDER BY, cambie eso, y me funciono perfecto!


Gracias por la ayuda!
  #4 (permalink)  
Antiguo 10/05/2009, 16:03
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Liado con SELECT.... JOIN....

Me alegro que te sirviera.
Si, la posición del GROUP BY y del ORDEN BY a veces se me cruza porque en la mayoría de las veces las manejo por separado dentro de subconsultas para hacer reportes, y eso me hace cometer el error.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 22/05/2009, 09:12
Avatar de DooBie  
Fecha de Ingreso: septiembre-2004
Mensajes: 1.101
Antigüedad: 19 años, 7 meses
Puntos: 71
Respuesta: Liado con SELECT.... JOIN....

Retomo el hilo, ya que es algo relevante a la misma consulta.
El caso es que cuando lo probe, no me di cuenta de una cosa, y es que la consulta que muy amablemente me dio gnzsoloyo, no me devuelve las categorias que no tengan productos.

Como podria solventar este inconveniente? es decir, que me devuelve las categorias con y sin productos, y las que tenga productos, que me diga cuantos tiene. La verdad que no se me ocurre como hacerlo, si es que se puede...
  #6 (permalink)  
Antiguo 22/05/2009, 09:33
Avatar de Genetix  
Fecha de Ingreso: febrero-2002
Ubicación: Lima - Perú
Mensajes: 1.600
Antigüedad: 22 años, 2 meses
Puntos: 45
Respuesta: Liado con SELECT.... JOIN....

Prueba Usando Left Join
Código sql:
Ver original
  1. SELECT
  2.    c.categoria ,
  3.    COUNT(*) productos
  4. FROM tbl_categorias c LEFT JOIN tbl_productos p ON c.id = p.id_categoria
  5. ORDER BY c.categoria
  6. GROUP BY c.categoria;

Saludos!
__________________
"El conocimiento nos hace responsables."
twitter: @benjamingb
blog personal: http://codigolinea.com
ZF Manual en español http://manual.zfdes.com
  #7 (permalink)  
Antiguo 22/05/2009, 09:54
Avatar de DooBie  
Fecha de Ingreso: septiembre-2004
Mensajes: 1.101
Antigüedad: 19 años, 7 meses
Puntos: 71
Respuesta: Liado con SELECT.... JOIN....

Cita:
Iniciado por Genetix Ver Mensaje
Prueba Usando Left Join
Código sql:
Ver original
  1. SELECT
  2.    c.categoria ,
  3.    COUNT(*) productos
  4. FROM tbl_categorias c LEFT JOIN tbl_productos p ON c.id = p.id_categoria
  5. ORDER BY c.categoria
  6. GROUP BY c.categoria;

Saludos!
He probado con LEFT JOIN con la consulta anterior, y me devolvia los mismos datos, es decir, las categorias con 0 productos no me las daba y me he puesto a probar consultas hasta que he dado con esta:
Código sql:
Ver original
  1. SELECT tbl_categorias . * , COUNT( * ) productos
  2. FROM tbl_categorias
  3. LEFT JOIN tbl_productos ON tbl_categorias.id = tbl_productos.id_categoria
  4. GROUP BY tbl_categorias.id
  5. ORDER BY tbl_categorias.id ASC
  6. LIMIT 0 , 30
la cual me devuelve las categorias con y sin productos, peeeero (siempre hay un pero), las categorias que no tienen productos, me las devuelve con un valor de 'productos' erroneo, en lugar de 0 me devuelve un 1, y me he asegurado que esa categoria no tenga productos relacionados.

Tambien he probado con RIGHT JOIN e INNER JOIN y me pasa una de dos, o no me devuelve todas las categorias, o me las devuelve con datos erroneos.

alguna idea?

Edito: El problema estaba en el COUNT(*). Al final la consulta me ha quedado asi:
Código sql:
Ver original
  1. SELECT tbl_categorias . * , COUNT( tbl_productos.id ) productos
  2. FROM tbl_categorias
  3. LEFT JOIN tbl_productos ON tbl_categorias.id = tbl_productos.id_categoria
  4. GROUP BY tbl_categorias.id
  5. ORDER BY tbl_categorias.id ASC

Última edición por DooBie; 22/05/2009 a las 10:16 Razón: Problema solucionado
  #8 (permalink)  
Antiguo 22/05/2009, 10:14
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Liado con SELECT.... JOIN....

Cita:
la cual me devuelve las categorias con y sin productos, peeeero (siempre hay un pero), las categorias que no tienen productos, me las devuelve con un valor de 'productos' erroneo, en lugar de 0 me devuelve un 1, y me he asegurado que esa categoria no tenga productos relacionados.
Eso es porque estás contando los registros de categorías, asumiendo que son productos y no es así. En ese caso tienes que determinar si son productos o NULL.
El tema se resuelve insertando en una subconsulta lo que estás haciendo ya, pero en vez de usar COUNT, hay que usar SUM():
Código sql:
Ver original
  1. SELECT
  2.    campos,
  3.    SUM(productos) Productos
  4. FROM
  5.    (SELECT
  6.       tbl_categorias . * ,
  7.      IF (P.id_categoria IS NULL, 0, 1) productos
  8.    FROM tbl_categorias C
  9.    LEFT JOIN tbl_productos P ON C.id = P.id_categoria) T1
  10. GROUP BY id
  11. ORDER BY id ASC
  12. LIMIT 0 , 30

Detalles: Este método requiere si o si que se indique por su nombre los campos que se desean recuperar. No funciona de otra forma y no se puede hacer que funcione de otro modo si lo que quieres es que te devuelva cero (0) en esa columna.
Tip: Si quieres que se ordene en forma ascendente no es necesario quee pongas ASC, porque ese es el modo por default. Es redundante. Tienes que ponerlo si previo hay otro campo puesto como DESC.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 22/05/2009, 11:18
Avatar de DooBie  
Fecha de Ingreso: septiembre-2004
Mensajes: 1.101
Antigüedad: 19 años, 7 meses
Puntos: 71
Respuesta: Liado con SELECT.... JOIN....

Igual no lo habias visto, pero, ya resolvi el problema con tan solo cambiar el count(*)
De todas formas, nunca esta de mas conocer diferentes formas de hacer las cosas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 04:59.