2009-12-20 3 views
0

나는 데이트 사이트에 대한 개인 메시징 시스템을 구축하고 있습니다. 쿼리로 그룹에 문제가 있습니다.그룹화/쓰레드 메시징 MySQL Prob

사용자가 다른 사용자에게 새로운 메시지를 전송
`id` bigint (20) NOT NULL AUTO_INCREMENT , 
`fromme` integer (11) NOT NULL, 
`tome` integer (11) NOT NULL, 
`subject` varchar (255) NOT NULL, 
`message` longtext NOT NULL, 
`mydate` datetime NOT NULL, 
`thread` varchar (255) NOT NULL, 
`receipt` varchar (50) NOT NULL, 
`INDELETE` varchar (5), 
`SENTDELETE` varchar (5), 
PRIMARY KEY (`id`) 

, 그것은 실을 추적하는 랜덤 문자열을 생성한다 : 여기서, 테이블의 구조는 다음과 같다. 그들은 회신하면서 스레드 문자열을 전달합니다 (페이스 북과 비슷 함). 사용자가 로그인하면받은 편지함에있는 모든 메시지를 볼 수 있으며 새 메시지인지 여부에 따라 행의 bg 색상이 변경됩니다. 이 모든 것은 앞뒤로 스레드 된 메시지의 수신 상태를 제외하고는 정상적으로 작동합니다.

select messages.id, messages.fromme, messages.subject, messages.message, messages.receipt, messages.mydate, messages.thread, users.firstname, users.lastname, users.image1 
from messages, users 
where messages.tome = '40' and messages.INDELETE !='y' and messages.fromme = users.id 
GROUP BY messages.thread 
ORDER BY messages.mydate desc 

그것은 제대로 반환하지만 기능에 의해 그룹이 thread..I의 첫 번째 메시지가 제대로 작동하도록하기 위해 최신 하나를 필요로 반환이 쿼리입니다. 누구든지이 일을 수행하는 방법을 알고 있습니까?

답변

1

GROUP BY 절을 사용하려면 집계 함수 (MAX, SUM, COUNT 등)가 필요합니다. 대답 @Ollie 존스가 잘 당신이

SELECT messages.id, 
     messages.fromme, 
     messages.subject, 
     messages.message, 
     messages.receipt, 
     messages.mydate, 
     messages.thread, 
     users.firstname, users.lastname, users.image1 
    FROM messages, 
     users, 
     (SELECT MAX(messages.id) id, messages.thread thread 
      FROM messages 
     GROUP BY messages.thread) latest, 
WHERE messages.tome = '40' 
    AND messages.INDELETE !='y' 
    AND messages.fromme = users.id 
    AND messages.id=latest.id 
ORDER BY messages.mydate desc 
2

를 사용할 수 있습니다 모두 함께 퍼팅

select MAX(messages.id) id, messages.thread 
FROM messages 
GROUP BY messages.thread 

: 당신은 아마 각 스레드에서 가장 최근의 (가장 높은 ID) 메시지를 해결하기 위해이 하위 쿼리를 사용하려면 (오래된 SQL-89 쉼표 스타일을 제외하고 구문을 가입), 그러나 무엇은 여기에 가치 것은 대안이다 :

SELECT m1.*, u.* 
FROM messages m1 
LEFT OUTER JOIN messages m2 
    ON (m1.thread=m2.thread AND m1.mydate < m2.mydate) 
JOIN users u ON (m1.fromme = u.id) 
WHERE m2.thread IS NULL; 

없음 GROUP BY이 필요합니다. 이는 각 행 m1을 동일한 스레드와 이후 날짜가있는 가정용 행 m2에 일치시킵니다. 일치하는 행이 m2 인 경우 m1이 스레드의 최신 메시지 여야합니다.

MySQL은 일반적으로 GROUP BY 개의 쿼리를 정렬 할 때 임시 테이블을 만들기 때문에이 솔루션은 MySQL에 유용합니다. 조인 솔루션은 종종 더 빠릅니다. (thread, mydate)에 인덱스가 있는지 확인하십시오.