2012-06-09 17 views
7

Estoy trabajando en un sistema de mensajería con dos tablas y otra con la información de los usuarios.
Una conversación puede tener entre 2 o más usuarios. Cada conversación tiene un UID y todos los mensajes intercambiados entre los usuarios están etiquetados con ese UID de conversación.Consulta del sistema de mensajería para obtener los últimos mensajes, el número de mensajes no leídos y la matriz de usuarios en la conversación

Estas son las tablas:

conversation_list: cada fila de esta tabla vincula el user_id y la conversation_id, sino que también contiene la última vez que el usuario ha visto la conversación.

`id`     -> unique ID, autoincremented 
`user_id`   -> This contains the user associated with the conversation. 
`conversation_id` -> This contains the UID of the conversation 
`date_lastView`  -> This field has the time that the user viewed the conversation last 

conversation_messages: cada fila de esta tabla contiene un mensaje

`id`     -> unique ID, autoincremented 
`user_id`   -> This contains the user that sent the message. 
`conversation_id` -> This contains the UID of the conversation 
`date_created`  -> This contains the time when the message was posted 
`message`   -> This contains the message 

users: cada fila de esta tabla contiene un usuario

`User_ID`   -> UID of the user 
`FirstName`   -> This contains the first name of the user 
`LastName`   -> This contains the last name of the user 

Ya tengo una consulta SQL para obtener el último mensaje de cada conversación. Aquí está:

SELECT * 
FROM conversation_messages AS m 

JOIN 
    (SELECT mx.conversation_id, 
      MAX(mx.date_created) AS MaxTime 
    FROM conversation_messages AS mx 
    GROUP BY mx.conversation_id) AS mx ON m.conversation_id = mx.conversation_id 
AND m.date_created = mx.MaxTime 

JOIN 
    (SELECT mu.conversation_id 
    FROM conversation_list AS mu 
    WHERE mu.user_id = :USER_ID_CONNECTED 
    GROUP BY mu.conversation_id) AS mux ON m.conversation_id = mux.conversation_id 

JOIN conversation_list AS mu ON m.conversation_id = mu.conversation_id 

GROUP BY mu.conversation_id 
ORDER BY m.date_created DESC 

Ahora me gustaría añadir a esta consulta en perfecta eficacia la capacidad de volver:

  • El número de mensajes no leídos para cada conversación (recuento de todos los mensajes con el date_creaded grande luego date_lastView del usuario que inició sesión)
  • Una matriz que contiene el User_ID de cada usuario en cada conversación y ordenada por la última vez que publicó un mensaje en la conversación.
  • Con la misma idea que la última matriz pero con FirstName y LastName del usuario.

Intenté algunas cosas pero no tuve éxito, así que ahora le pido a la comunidad SO su valiosa ayuda. .

Todos esto sólo puede conversaciones pantalla donde el usuario conectado participa en

Se le ayuda, he creado un SQLFiddle

+0

Una pregunta bien escrito 1. – Ben

+0

Otro +1 para el violín. – JStead

Respuesta

2

número de mensajes no leídos en la conversación del usuario (en este caso el usuario # 6):

SELECT l.conversation_id, count(*) 
FROM conversation_list l 
JOIN conversation_messages m ON m.conversation_id = l.conversation_id AND m.date_created > l.date_lastview 
WHERE l.user_id = 6 
GROUP BY l.conversation_id 

Los participantes en las conversaciones ordenadas por última actividad:

SELECT conversation_id, user_id, max(date_created) as last_active 
FROM conversation_messages 
GROUP BY conversation_id, user_id 
ORDER BY conversation_id, last_active 

La tercera consulta debe ser igual que la segunda, simplemente se une a una tabla más en el user_id, ¿verdad?

+0

Bueno, sabía cómo hacer esto, pero mi gran problema es implementar esto en el código SQL que tengo en mi pregunta. –

+0

No entiendo ... – doublep

+0

Me gustaría obtener toda esta información en una sola consulta a la base de datos. –

0

he añadido 3 mejoras a the query to fetch the unread messages:

  • Si el campo last_view es nulo, se asumirá que el usuario nunca comprobar sus mensajes, por lo que todos los mensajes será "sin leer"
  • Identificar como nueva mensajes solo los que no fueron creados por el usuario.
  • Cuando no hay mensajes no leídos, el recuento volverá 0
SELECT l.conversation_id, count(m.id) 
FROM conversation_list l 
LEFT JOIN conversation_messages m ON m.conversation_id = l.conversation_id AND (l.date_lastview IS NULL OR m.date_created > l.date_lastview) AND m.user_id != 6 
WHERE l.user_id = 6 
GROUP BY l.conversation_id 
Cuestiones relacionadas