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

[SOLUCIONADO] Group By o Join?

Estas en el tema de Group By o Join? en el foro de Mysql en Foros del Web. Hola Amigos, vengo a preguntaros lo siguiente: Tengo una tabla (gestiones) con estos campos id_gestion id_vendedor id_cliente sop id_inmueble fecha tipo Necesito sacar, para un ...
  #1 (permalink)  
Antiguo 08/03/2018, 10:04
 
Fecha de Ingreso: noviembre-2011
Ubicación: Sevilla
Mensajes: 39
Antigüedad: 13 años
Puntos: 1
Group By o Join?

Hola Amigos, vengo a preguntaros lo siguiente:
Tengo una tabla (gestiones) con estos campos
id_gestion id_vendedor id_cliente sop id_inmueble fecha tipo

Necesito sacar, para un inmueble (en los datos de prueba H250) las 5 últimas gestiones realizadas de distintos clientes (es decir, una por cliente, siempre la más nueva, la de fecha mayor)

Si le hago:
SELECT * FROM gestiones WHERE id_gestion IN (SELECT id_gestion FROM gestiones WHERE sop='H' AND id_inmueble='250' ORDER BY fecha DESC) GROUP BY id_cliente;


Me saca esto:

id_gestion id_vendedor id_cliente sop id_inmueble fecha tipo
36 27 725 H 250 03/03/2016 0:00 C
50 27 734 H 250 14/10/2015 0:15 A
61 27 735 H 250 12/02/2016 0:00 V
192 27 784 H 250 26/05/2016 8:30 A
196 27 785 H 250 04/06/2016 20:00 A
369 27 851 H 250 10/10/2016 10:00 A
418 27 872 H 250 25/11/2016 10:00 A
440 27 885 H 250 18/10/2016 9:00 A
571 27 928 H 250 27/04/2017 10:00 A
819 27 1008 H 250 17/10/2017 0:00 A

Donde podéis ver que algunas sí saca la correcta, y en cambio de otras, me saca la más antigua. En qué me equivoco?

Los resultados de sacar todas las gestiones de H250

SELECT * FROM gestiones WHERE sop='H' AND id_inmueble='250' ORDER BY fecha DESC;

Son estos:

id_gestion id_vendedor id_cliente sop id_inmueble fecha tipo
36 27 725 H 250 03/03/2016 0:00 C
35 27 725 H 250 16/11/2015 0:00 V
34 27 725 H 250 10/11/2015 0:00 A
50 27 734 H 250 14/10/2015 0:15 A
51 27 734 H 250 14/10/2015 0:15 A
52 27 734 H 250 15/10/2015 9:30 C
53 27 734 H 250 16/10/2015 11:00 V
55 27 734 H 250 17/02/2016 16:15 C
56 27 734 H 250 20/02/2016 10:00 C
61 27 735 H 250 12/02/2016 0:00 V
192 27 784 H 250 26/05/2016 8:30 A
193 27 784 H 250 30/05/2016 14:00 B
196 27 785 H 250 04/06/2016 20:00 A
197 27 785 H 250 06/06/2016 10:00 B
369 27 851 H 250 10/10/2016 10:00 A
370 27 851 H 250 10/10/2016 13:00 V
418 27 872 H 250 25/11/2016 10:00 A
419 27 872 H 250 25/11/2016 10:30 C
420 27 872 H 250 25/11/2016 17:00 V
440 27 885 H 250 18/10/2016 9:00 A
441 27 885 H 250 19/01/2017 2:30 C
571 27 928 H 250 27/04/2017 10:00 A
572 27 928 H 250 27/04/2017 12:00 X
819 27 1008 H 250 17/10/2017 0:00 A
820 27 1008 H 250 18/10/2017 10:00 P


Gracias!
  #2 (permalink)  
Antiguo 08/03/2018, 11:16
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 18 años, 3 meses
Puntos: 774
Respuesta: Group By o Join?

Código SQL:
Ver original
  1. SELECT * FROM tabla AS t1
  2. LEFT JOIN
  3. (
  4. SELECT MAX(fecha) AS feca, id FROM tabla GROUP BY id
  5. ) AS t2 ON (t1.fecha=t2.fecha AND t1.id=t2.id)

Also asi
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #3 (permalink)  
Antiguo 08/03/2018, 13:24
 
Fecha de Ingreso: noviembre-2011
Ubicación: Sevilla
Mensajes: 39
Antigüedad: 13 años
Puntos: 1
Respuesta: Group By o Join?

Hola Libras, gracias por tu respuesta.

No entiendo muy bien tu sentencia SQL y copiada y pegada no funciona, así que te pregunto mis dudas:

ELECT * FROM tabla AS t1
LEFT JOIN
(
SELECT MAX(fecha) AS feca, id FROM tabla GROUP BY id
) AS t2 ON (t1.fecha=t2.fecha AND t1.id=t2.id)

Ese "feca" está puesto así queriendo como alias?
esos id son los del cliente o los del inmueble?
como reconoce esa sentencia que tiene que sacar las gestiones del inmueble con sop=H e id=250?

Gracias!
  #4 (permalink)  
Antiguo 08/03/2018, 13:41
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 18 años, 3 meses
Puntos: 774
Respuesta: Group By o Join?

es solo para que te des una idea de como hacerlo, lo que estoy haciendo es sacando las fechas maximas de cada id,producto o como tu lo tengas, y de ahi uniendolo a la misma tabla, no te va a resolver tu problema nada mas ejecutandolo, no lo hice para eso sino para que veas como se podria resolver
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #5 (permalink)  
Antiguo 12/03/2018, 05:00
 
Fecha de Ingreso: noviembre-2011
Ubicación: Sevilla
Mensajes: 39
Antigüedad: 13 años
Puntos: 1
Respuesta: Group By o Join?

Hola Libras y gracias de nuevo por responder. Agradezco que me hagas pensar y a ver si de una vez consigo comprender los left join, que no se me dan nada bien. El problema es que no logro entender la lógica de la consulta que propones.
  #6 (permalink)  
Antiguo 12/03/2018, 19:56
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 15 años, 2 meses
Puntos: 214
Respuesta: Group By o Join?

Saludo

Pues a mi se me ocurre esto

Código SQL:
Ver original
  1. SELECT * FROM gestiones
  2. WHERE id_gestion IN (SELECT MAX(id_gestion) FROM gestiones WHERE sop='H' AND id_inmueble='250' GROUP BY id_cliente ORDER BY fecha DESC)
  3. ORDER BY fecha DESC;
__________________
"Si consigues ser algo más que un hombre, si te entregas a un ideal, si nadie puede detenerte, te conviertes en algo muy diferente."
Visita piggypon.com
  #7 (permalink)  
Antiguo 13/03/2018, 07:35
 
Fecha de Ingreso: noviembre-2011
Ubicación: Sevilla
Mensajes: 39
Antigüedad: 13 años
Puntos: 1
Respuesta: Group By o Join?

Gracias Mortiprogramador, funciona a las mil maravillas. Además me resulta mucho más sencillo entender esa sentencia.
  #8 (permalink)  
Antiguo 13/03/2018, 08:47
Avatar de Libras
Colaborador
 
Fecha de Ingreso: agosto-2006
Ubicación: En la hermosa perla de occidente
Mensajes: 7.412
Antigüedad: 18 años, 3 meses
Puntos: 774
Respuesta: Group By o Join?

La logica es la misma, solo que en lugar de un IN usas un subquery, que es muchisimo mas eficiente a nivel base de datos que un IN
__________________
What does an execution plan say to t-sql query? Go f**k yourself, if you are not happy with me
  #9 (permalink)  
Antiguo 17/03/2018, 08:03
Avatar de mortiprogramador
Colaborador
 
Fecha de Ingreso: septiembre-2009
Ubicación: mortuoria
Mensajes: 3.805
Antigüedad: 15 años, 2 meses
Puntos: 214
Respuesta: Group By o Join?

De nada Lucky_Sky, sin embargo la solución que daba Libras era algo así:

Código SQL:
Ver original
  1. SELECT * FROM gestiones g1
  2. LEFT JOIN
  3. (
  4.     SELECT MAX(fecha) fecha, id_gestion FROM gestiones ORDER BY fecha DESC
  5. ) g2 ON (g1.fecha = g2.fecha AND g1.id_gestion = g2.id_gestion)
  6. WHERE sop = 'H' AND id_inmueble = '250' GROUP BY id_cliente;

Y teniendo en cuenta lo del rendimiento, haciendo explain de ambas consultas
veo lo siguiente:

Código BASH:
Ver original
  1. Usando IN
  2. +----+--------------------+------------------+-----------------+---------------+---------+---------+------+------+----------------------------------------------+                                                                                                                                                        
  3. | id | select_type        | table            | type            |  possible_keys | key     | key_len | ref  | rows | Extra                                         |                                                                                                                                                      
  4. +----+--------------------+------------------+-----------------+---------------+---------+---------+------+------+----------------------------------------------+                                                                                                                                                        
  5. |  1 | PRIMARY            | gestiones        | ALL             | NULL           | NULL    | NULL    | NULL |   25 | Using where; Using temporary;  Using filesort |                                                                                                                                                      
  6. |  2 | DEPENDENT SUBQUERY | gestiones        | unique_subquery | PRIMARY        | PRIMARY | 4       | func |    1 | Using where                                   |                                                                                                                                                      
  7. +----+--------------------+------------------+-----------------+---------------+---------+---------+------+------+----------------------------------------------+                                                                                                                                                                                                                                                                                                      
  8. Usando LEFT JOIN
  9. +----+-------------+------------------+------+---------------+------+---------+------+------+----------------------------------------------+
  10. | id | select_type | table            | type | possible_keys | key  | key_len | ref  | rows | Extra                                        |
  11. +----+-------------+------------------+------+---------------+------+---------+------+------+----------------------------------------------+
  12. |  1 | PRIMARY     | g1               | ALL  | NULL          | NULL | NULL    | NULL |   25 | Using where; Using temporary; Using filesort |
  13. |  1 | PRIMARY     | <derived2>       | ALL  | NULL          | NULL | NULL    | NULL |    1 |                                              |
  14. |  2 | DERIVED     | gestiones        | ALL  | NULL          | NULL | NULL    | NULL |   25 | Using temporary                              |
  15. +----+-------------+------------------+------+---------------+------+---------+------+------+----------------------------------------------+

Luego, agregando algunos index sobre los campos claves de la consulta

Código BASH:
Ver original
  1. Usando IN
  2. +----+--------------------+------------------+-----------------+------------------------------+---------+---------+------+------+-------------+
  3. | id | select_type        | table            | type            | possible_keys                | key     | key_len | ref  | rows | Extra       |
  4. +----+--------------------+------------------+-----------------+------------------------------+---------+---------+------+------+-------------+
  5. |  1 | PRIMARY            | gestiones        | index           | NULL                         | index6  | 5       | NULL |   25 | Using where |
  6. |  2 | DEPENDENT SUBQUERY | gestiones        | unique_subquery | PRIMARY,index3,index4,index5 | PRIMARY | 4       | func |    1 | Using where |
  7. +----+--------------------+------------------+-----------------+------------------------------+---------+---------+------+------+-------------+
  8. Usando LEFT JOIN
  9. +----+-------------+------------------+-------+---------------+--------+---------+------+------+----------------------------------------------+
  10. | id | select_type | table            | type  | possible_keys | key    | key_len | ref  | rows | Extra                                        |
  11. +----+-------------+------------------+-------+---------------+--------+---------+------+------+----------------------------------------------+
  12. |  1 | PRIMARY     | g1               | ALL   | index3,index4 | NULL   | NULL    | NULL |   25 | Using where; Using temporary; Using filesort |
  13. |  1 | PRIMARY     | <derived2>       | ALL   | NULL          | NULL   | NULL    | NULL |    1 |                                              |
  14. |  2 | DERIVED     | gestiones        | index | NULL          | index2 | 9       | NULL |   25 | Using index; Using temporary                 |
  15. +----+-------------+------------------+-------+---------------+--------+---------+------+------+----------------------------------------------+


Y aprovechando a Libras, quisiera saber un poco más sobre estas diferencias,
y la eficiencia, con eso tal vez Lucky_Sky se anime a usar esa solución.
__________________
"Si consigues ser algo más que un hombre, si te entregas a un ideal, si nadie puede detenerte, te conviertes en algo muy diferente."
Visita piggypon.com

Última edición por mortiprogramador; 17/03/2018 a las 08:40

Etiquetas: select
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 11:22.