2012-08-28 21 views
8

permite decir esto es la estructura de base de datos:Sistema privado de mensajes. Añadir último mensaje de cada conversación

enter image description here

SELECT * FROM `pms` where id_to = 1 or id_from = 1 

Esto devolverá todos los mensajes que ha Recived o enviados,

Entonces, ¿cómo puedo recuperar el último mensaje de cada conversación que el usuario 1 puede tener?

PD: Me llaman la conversación cuando hay uno o más mensajes entre dos usuarios

operación -Editar-

Así que dado este contenido base de datos:

enter image description here

queremos llegar id 4 y 6

Respuesta

7

Esto supone id es una columna de incremento automático:

SELECT MAX(id) AS id 
FROM pms 
WHERE id_to = 1 OR id_from = 1 
GROUP BY (IF(id_to = 1, id_from, id_to)) 

Asumiendo que tiene id_from y id_to indexados, esta variación lo más probable es obtener mejores resultados ya que MySQL no sabe qué hacer con un OR:

SELECT MAX(id) AS id FROM 
(SELECT id, id_from AS id_with 
FROM pms 
WHERE id_to = 1 
UNION ALL 
SELECT id, id_to AS id_with 
FROM pms 
WHERE id_from = 1) t 
GROUP BY id_with 

Aquí es cómo conseguir los mensajes de los identificadores de:

SELECT * FROM pms WHERE id IN 
    (SELECT MAX(id) AS id FROM 
    (SELECT id, id_from AS id_with 
    FROM pms 
    WHERE id_to = 1 
    UNION ALL 
    SELECT id, id_to AS id_with 
    FROM pms 
    WHERE id_from = 1) t 
    GROUP BY id_with) 
+0

¡Esto parece funcionar! Le daré un poco de prueba y le haré saber. ¡Gracias! –

+0

@ToniMichelCaubet, otra actualización para devolver el mensaje completo. –

+0

¿Esto funciona mejor? –

1

Esta consulta debería funcionar:

SELECT a.* 
FROM pms a 
    INNER JOIN (
       SELECT id_to, id_from, MAX(fecha) AS fecha 
       FROM pms 
       WHERE (id_to = 1 OR id_from = 1) 
       GROUP BY LEAST(id_to, id_from) 
       ) b 
       ON a.fecha = b.fecha AND 
        (a.id_to = b.id_to OR 
        a.id_from = b.id_from); 

See example @ sqlfiddle here

Si tiene id como PRIMARY KEY y anotar los mensajes en un orden cronológico, a continuación, se puede optimizar aún más y simplificar como:

SELECT a.* 
FROM pms a 
    INNER JOIN (
       SELECT MAX(id) AS id 
       FROM pms 
       WHERE (id_to = 1 OR id_from = 1) 
       GROUP BY LEAST(id_to, id_from) 
       ) b 
       ON a.id = b.id; 
+0

Se informaron los siguientes errores: Cada tabla derivada debe tener su propio alias –

+0

ohh ok .. olvidó alis para la tabla derivada 'b'. consulta actualizada, prueba ahora. – Omesh

+0

gosh ... Se informaron los siguientes errores: Columna 'id_to' en donde cláusula es ambigua –

3
select pms.* from pms 
inner join 
    (select max(fecha) as max_fecha, 
      if(id_to<id_from,id_to,id_from) min_id, 
      if(id_to<id_from,id_from,id_to) max_id 
     from pms where id_to = 1 or id_from = 1 
     group by if(id_to<id_from,id_to,id_from),if(id_to<id_from,id_from,id_to)) t 
    on (if(pms.id_to<pms.id_from,pms.id_to,pms.id_from)=t.min_id) 
     and (if(pms.id_to<pms.id_from,pms.id_from,pms.id_to)=t.max_id) 
     and (pms.fecha=t.max_fecha) 

También si id_to y id_from en su tabla son lo suficientemente pequeños para evitar el desbordamiento en la instrucción (id_to + id_from) aquí está la consulta simple:

select pms.* from pms 
inner join 
    (select max(fecha) as max_fecha, id_to+id_from as sum_id 
     from pms where id_to = 1 or id_from = 1 
     group by id_to+id_from) t 
    on ((pms.id_to+pms.id_from)=t.sum_id) 
     and (pms.fecha=t.max_fecha) 
where pms.id_to = 1 or pms.id_from = 1 
+0

Esto muestra el último mensaje de cada usuario de cada conversación Está cerca, pero solo queremos el último mensaje de cada conversación –

+1

Por favor, intente con la consulta fija. – valex

+0

funciona !!! le dará algunas pruebas y le hará saber –

Cuestiones relacionadas