Pergunta

Actualmente tenho as seguintes tabelas para um fórum de mensagens particulares:

alt texto http://img159.imageshack.us/img159/45/pmdata .jpg

alt texto http://img504.yfrog.com/img504/3968/pminfo .jpg

O que eu estou tentando fazer é emitir uma "caixa de entrada" que exibe o segmento mais recente no topo e agrupar por thread (ou seja, você não vê o mesmo segmento duas vezes em sua caixa de entrada), não importa quem o remetente é.

O que eu tenho agora funciona bem para mensagens simples entre 2 uesrs. No entanto, uma vez que um terceiro usuário responde ao mesmo segmento, ele não é exibido corretamente. Minha consulta atual é esta:

SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent,  pm_data.title, pm_data.thread_id, pm_data.id as dataid, thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
INNER JOIN (SELECT thread_id, sender_id, MAX(date_sent) AS thread_max_date_sent FROM pm_data GROUP BY thread_id, sender_id) deriv1 ON pm_data.thread_id = deriv1.thread_id AND pm_data.date_sent = deriv1.thread_max_date_sent AND pm_data.sender_id = deriv1.sender_id
WHERE pm_info.receiver_id = '$usrID'
ORDER BY deriv1.thread_max_date_sent DESC

Assumindo que usrID $ = 68 (daí, receiver_id = 68), ele produz este:

From: Kyle (pm_data.id = 18) RE: single message (thread_id= 13587)
From: Ed (pm_data.id = 12)   RE: single message (thread_id= 13587)
From: Ed (pm_data.id = 8)    RE: Test Number 2 (thread_id= 16256)

Note como o thread_id (13587) aparece duas vezes, porque existem 2 emissores diferentes.

Como eu poderia tê-lo apenas exibir o thread_id recente mais, não importa quem é o remetente?

Muito obrigado !!

Foi útil?

Solução

Na verdade, parece que a consulta na pergunta original requer apenas uma mudança muito pequena para obter o real registro mais recente para cada segmento.

  1. largar o SENDER_ID no grupo do subconsulta por campos
  2. largar o pm_data.sender_id = deriv1.sender_id na cláusula ON
SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent,  pm_data.title, pm_data.thread_id, pm_data.id as dataid, thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
INNER JOIN (SELECT thread_id, /*sender_id,*/ MAX(date_sent) AS thread_max_date_sent 
                FROM pm_data GROUP BY thread_id /*, sender_id*/) deriv1 
    ON pm_data.thread_id = deriv1.thread_id AND pm_data.date_sent = deriv1.thread_max_date_sent /*AND pm_data.sender_id = deriv1.sender_id*/
WHERE pm_info.receiver_id = '$usrID'
ORDER BY deriv1.thread_max_date_sent DESC

Como uma nota lateral: se possível, olhar para o messageID max em que subconsulta em vez de max (date_sent)

Outras dicas

Tente

SELECT pm_info.is_read, sender.usrFirst as sender_name, pm_data.date_sent,  pm_data.title, pm_data.thread_id, pm_data.id as dataid
FROM pm_data, pm_info, tblUsers as sender 
WHERE pm_info.message_id = pm_data.id 
  AND pm_data.sender_id = sender.usrID
  AND pm_info.receiver_id = '$usrID'
GROUP BY thread_id
ORDER BY date_sent DESC
LIMIT 0,1

Tente

SELECT pm_info.is_read, group_concat(DISTINCT sender.usrFirst) as sender_name,
    pm_data.date_sent, pm_data.title, pm_data.thread_id, pm_data.id as dataid,
    MAX(date_sent) AS thread_max_date_sent
FROM pm_info
INNER JOIN pm_data ON pm_info.message_id = pm_data.id
INNER JOIN tblUsers AS sender ON pm_data.sender_id = sender.usrID
WHERE pm_info.receiver_id = '$usrID'
GROUP BY pm_data.thread_id
ORDER BY thread_max_date_sent DESC;

Sinta-se livre para discordar com a parte group_concat, se ele não atender às suas necessidades; ele simplesmente lista todos os remetentes relevantes em vez de escolher um arbitrariamente.

A minha sugestão seria a de dividir o seu banco de dados em duas tabelas para uma melhor normalização: "thread" e "mensagem". Há informações segmento que seria comum a todas as mensagens, como o título fio. Você está perdendo espaço na tabela de mensagens, repetindo os mesmos valores.

Você pode ter um campo "última vez post" mesa de fio, que é atualizado a cada novo post. Então é só uma questão simples de seleção da tabela de linha e ordenação pelo último post. Será muito mais rápido também.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top