2012-06-26 5 views
1

우선 나는 비슷한 질문을 여기에서 물어 보았다. 나는 점검했지만 문제에 대한 적절한 해결책을 찾지 못했다.MySQL 그룹 가입 및 선택

나는이 두 테이블 (단순에만 필요한 부분에 트리밍)이 있습니다

CREATE TABLE messages(
message_id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, 
message_conversation_id MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', 
message_from MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', 
message_to MEDIUMINT(8) UNSIGNED NOT NULL DEFAULT '0', 
message_text TEXT NOT NULL DEFAULT '', 
PRIMARY KEY (message_id), 
KEY message_conversation_id (message_conversation_id), 
KEY message_from (message_from), 
KEY message_to (message_to) 
) ENGINE=INNODB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 

CREATE TABLE users (
user_id MEDIUMINT(8) UNSIGNED NOT NULL AUTO_INCREMENT, 
user_name VARCHAR(400) NOT NULL DEFAULT '', 
PRIMARY KEY (user_id) 
) ENGINE=INNODB DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 

내가 최대 MESSAGE_ID의 MESSAGE_TEXT을 표시하는 쿼리를 만들어 원하는, 모두 message_from에 저장 될 수있는 사용자의 정보 (또는 message_to를 사용하고 where 절로 필터링하면 (간단히 : 메시지가 나에게 올 것이며 다른 사용자의 사용자 정보를 제공합니다. 그 대화에서 마지막 메시지는 나 또는 다른 대화 상대가 될 수 있기 때문입니다) 해결)).

이 쿼리는 지금까지 해낸 것입니다 :

SELECT `m`.*, `u`.*, `u2`.* 
FROM (`messages` AS m) 
INNER JOIN `users` AS u ON `u`.`user_id`=`m`.`message_from` 
INNER JOIN `users` AS u2 ON `u2`.`user_id`=`m`.`message_to` 
WHERE (m.message_from="1" OR m.message_to="1") 
AND `u`.`user_id` != '1' 
AND `u2`.`user_id` != '1' 
GROUP BY `m`.`message_conversation_id` 
ORDER BY `m`.`message_id` desc 

이 쿼리는 메시지 테이블에서 가장 낮은 값을 제공 제외하고 내가 (내 생각)가 필요합니다 정확히 보여줍니다.

어떻게하면됩니까? 내가 어디에서 잘못하고 있니? 나는이 방법이 필요 걸 얻었

답변

2

여기에 각 대화의 최신 메시지를받는 다른 방법이 있습니다. "임무 수행"수단

SELECT m.*, u.*, u2.* 
FROM (`messages` AS m) 
LEFT JOIN users AS u ON u.user_id=m.message_from 
LEFT JOIN users AS u2 ON u2.user_id=m.message_to 
WHERE (m.`message_from` != 1 AND m.`message_to` != 1) AND m.`message_id` IN (
    SELECT MAX(`message_id`) 
    FROM `messages` 
    GROUP BY `message_conversation_id` 
    HAVING `message_id` = m.`message_id`) 
ORDER BY m.message_id DESC; 

는 이것을 설명, 결과는 "인덱스를 사용하여 여기서"이다.

+0

고마워, 내가 시도하고 함께 할 수없는 동안 내 접근 방식이 더 좋아, 완벽하게 작동, 감사합니다! – Arda

+0

하나의 문제 만 남아 있지만 대화의 정보에 다른 사람이 아니라 내 ID와 정보를 반환합니다. 가능하다면 코드를 업데이트 해 주실 수 있습니까? – Arda

+0

답변이 업데이트되었습니다. 오직 'message_from'과'message_to'를 1 (my id)와 같지 않게 변경합니다. – silverfox

0

덕분에, 내가 필요하면 MESSAGE_BODY 결과 열이다. 이것은 건강한가 아니면 다른 (더 나은) 방법이 있습니까?

SELECT DISTINCT(m.message_conversation_id),max(m.message_id), m.*,u.*, u2.*, 
(SELECT m2.message_text FROM messages m2 WHERE m2.message_id = max(m.message_id)) AS 'message_body' 
FROM (`messages` AS m) 
LEFT JOIN users AS u ON u.user_id=m.message_from 
LEFT JOIN users AS u2 ON u2.user_id=m.message_to 
WHERE (m.message_from='1' OR m.message_to='1') 
GROUP BY m.message_conversation_id 
ORDER BY m.message_id DESC 
+2

[EXPLAIN] (http://dev.mysql.com/doc/refman/5.1/en/explain.html) 답변을 mysql에 입력하십시오. 결과 "임시 사용 : 파일 사용"은 대용량 데이터 세트에서 효율적이지 않다는 것을 의미합니다. – silverfox