2012-10-24 6 views
3

나는 테이블을 가지고 : messages이 구조 :선택 별개의 기록은

`ID` // auto increment 
`SenderUserID` // foreign key: `ID` from `User` table 
`ReceiverUserID` // foreign key: `ID` from `User` table 
`Message` 
`DateCreated` // timestamp 
나는이 조건 테이블 구별 ReceiverUserIDs을 얻을 필요가

:

  1. 보낸 사람 사용자는 수신자 사용자와 대화해야합니다.
  2. 고유 한 ReceiverUserID을 선택하면 마지막으로 DateCreated 메시지를 보내야합니다.

결과에서 사용자가 만든 마지막 대화는 DESC 생성 일순으로 정렬됩니다.

mysql이 첫 번째 레코드를 반환하지만, 선택된 ReceiverUserID가 결과 상단에 최대 값을 얻으려면 최대 값 DateCreated이 필요합니다.

SELECT DISTINCT `m`.`ReceiverUserID` AS `ID` FROM `messages` `m` 
WHERE (`m`.`SenderUserID` = :UserID OR `m`.`ReceiverUserID` = :UserID) 
ORDER BY `m`.`DateCreated` DESC 

//:UserID means LogedInUserID 

페이스 북 메시지 게시판과 정확히 일치합니다.


ID, SenderUserID, ReceiverUserID, Message, DateCreated 
1, 12, 11, 'Hi admin', 2012-10-24 11:07:00 
2, 11, 12, 'Hi guy', 2012-10-24 11:08:00 
3, 11, 13, 'Hello dear customer', 2012-10-24 11:12:00 
4, 11, 13, 'Are you there?', 2012-10-24 11:13:00 
5, 13, 11, 'Hiiii', 2012-10-24 11:14:00 // last conversation betwen 11 & 13 

현재 logedin 사용자 ID : 11

SELECT `m`.`ReceiverUserID` AS `ID`, MAX(`m`.`DateCreated`) as `lastmsg` 
FROM `messages` `m` WHERE (`m`.`SenderUserID` = 11 OR `m`.`ReceiverUserID` = 11) 
GROUP BY `m`.`ReceiverUserID` 

우리는이 부분에 문제가 : 그것은 수신기 사용자가 보낸 메시지를 대답 (11) 및 (13) 사이에 우리의 마지막 대화를 반환하지 않습니다 결과에 표시되지 않습니다.

결과 :

ID, lastmsg 
12, 2012-10-24 11:08:00 
13, 2012-10-24 11:13:00 // Should be: 13, 2012-10-24 11:14:00 

답변

0

...

SELECT `ID`, MAX(`lastmsg`) FROM 
( SELECT `m`.`ReceiverUserID` AS `ID`, MAX(`m`.`DateCreated`) as `lastmsg` FROM `messages` `m` 
    WHERE `m`.`SenderUserID` = :UserID 
    GROUP BY `m`.`ReceiverUserID` 
    UNION 
    SELECT `m`.`SenderUserID` AS `ID`, MAX(`m`.`DateCreated`) as `lastmsg` FROM `messages` `m` 
    WHERE `m`.`ReceiverUserID` = :UserID 
    GROUP BY `m`.`SenderUserID` 
) as table2 GROUP BY `ID` ORDER BY `lastmsg` 
+0

좋은 생각 인 것 같지만 문제는 아직 해결되지 않았습니다. 질문에 대한 새로운 세부 정보를 참조하십시오. – hallaji

+0

가 변경되면 수신자와 수신자를 구분해야합니다. – JaMaBing

+0

잘 했어! 내가 생각하는 실수가있다 : 첫 번째 : GROUP BY'm'.ReceiverUserID' 두 번째이어야합니다 : GROUP BY'm'.SenderUserID' 이 방법으로 내 솔루션을 얻었다. 고마워요 – hallaji

0

그냥 MAX를 사용 하시겠습니까?

SELECT ReceiverUserID, MAX(DateCreated) AS LatestDateCreated 
    FROM messages 
    WHERE (SenderUserID = :UserID OR ReceiverUserID = :UserID) 
GROUP BY ReceiverUserID 

편집

이 사용 해보세요 : - 당신이 SenderUserID와 동일한 작업을 수행 할 필요가 언급 한 바와 같이

SELECT IF(SenderUserID =11, ReceiverUserID, SenderUserID) AS ID, MAX(DateCreated) AS LatestDateCreated 
FROM messages 
WHERE (SenderUserID =11 
OR ReceiverUserID =11 
) 
GROUP BY IF(SenderUserID =11, ReceiverUserID, SenderUserID) 
+0

아니오, 그것은 단지 마지막 사용자의 대화를 반환됩니다! 모든 수신자 사용자 대화 목록이 필요합니다 – hallaji

+0

내가 실수로 놓친 GROUP BY를 추가하여 편집했습니다. – Kickstart

+0

좋은 생각 인 것 같습니다. 그러나 문제는 아직 해결되지 않았습니다. 질문에 대한 새로운 세부 정보를 참조하십시오. – hallaji

2

당신이 경우 현재 기능과 작업 흐름을 모두 유지하면서 데이터를 단일 테이블에 보관할 수있는 방법을 묻습니다. 당신이 꽤 귀엽다고 생각합니다. 오세.

conversationId가 다른 테이블의 키가되는 대신 대화를 시작한 메시지의 ID를 가리 키도록합니다. 이렇게하면 대화를 시작한 메시지와 그 뒤에 오는 모든 메시지 사이에 부모 - 자식 관계가 생성됩니다. 모든 대화를 볼 수 있으려면 conversationId가 null 인 모든 메시지를 선택하면됩니다. 다음은 2 메시지 대화의 표현입니다.

+----+---------+------+------------------+----------------+--------+----------+ 
| id | message | read | time    | conversationId | toUser | fromUser | 
+----+---------+------+------------------+----------------+--------+----------+ 
| 1 | test 1 | 0 | (some timestamp) | null   | 3  | 4  | 
| 2 | test 2 | 0 | (some timestamp) | 1   | 4  | 3  | 
+----+---------+------+------------------+----------------+--------+----------+ 

대화는 사용자 3에 의해 시작되었습니다. 대화의 모든 메시지는 대화 ID별로 필터링 할 수 있습니다. 이 디자인의 한 가지 한계는 단지 2 명의 사용자 만이 대화를 할 수 있다는 것입니다.

업데이트

당신은 대화 ID를 이런 식으로 주어진 마지막 메시지를 얻을 수 :

SELECT id, message 
    FROM userMessages 
    WHERE conversationId = {conversationId} 
    ORDER BY time DESC 
    LIMIT 1