2013-06-13 4 views
0

그래서 아래와 같은 SQL 테이블이 있습니다. 이 테이블은 사람들 사이의 SMS 메시지의 묶음입니다. 존재하는 모든 스레드를 얻고 싶습니다. 이것은 기본적으로 두 사람 사이의 마지막 메시지를 의미합니다. 어떻게해야합니까?두 개의 열에 대해 고유 한 SQL

------------------------------------------------------- 
| sender_id | receiver_id | message | time   | 
------------------------------------------------------- 
| 123  | 456   | hi  | 4/17/2013 | 
-------------------------------------------------------- 
| 123  | 111   | hi  | 4/18/2013 | 
-------------------------------------------------------- 
| 123  | 555   | hi  | 4/19/2013 | 
-------------------------------------------------------- 
| 555  | 123   | hi  | 4/20/2013 | 
-------------------------------------------------------- 
| 444  | 333   | hi  | 4/21/2013 | 
-------------------------------------------------------- 
| 123  | 555   | hi  | 4/22/2013 | 
-------------------------------------------------------- 
| 777  | 123   | hi  | 4/23/2013 | 
-------------------------------------------------------- 

나는 사용자 = 123 아래로 응답 행을 좀하고 싶습니다. sender_id와 receiver_id가 전체적으로 어떻게 고유한지 주목하십시오. joe가 bob에게 보낸 메시지가 bob이 joe에게 보낸 메시지와 동일한 스레드에 있음을 의미합니다.

------------------------------------------------------- 
| sender_id | receiver_id | message | time   | 
------------------------------------------------------- 
| 123  | 456   | hi  | 4/17/2013 | 
-------------------------------------------------------- 
| 123  | 111   | hi  | 4/18/2013 | 
-------------------------------------------------------- 
| 123  | 555   | hi  | 4/22/2013 | 
-------------------------------------------------------- 
| 777  | 123   | hi  | 4/23/2013 | 
-------------------------------------------------------- 
+0

어떤 데이터베이스 엔진입니까? – Blorgbeard

+0

매우 엔진에 따라 다릅니다. –

+0

다음 번에 My Code – codeNinja

답변

4

더 쉬운 제대로 일 주문을 처리하는 버전을 읽을 수 있도록 (질문 참조) 인덱스를 사용합니다 :

SELECT sender_id, receiver_id, message, time FROM 
(
SELECT sender_id, receiver_id, message, time 
FROM myTable 
WHERE sender_id = 123 OR receiver_id = 123 
ORDER BY time DESC 
) a 
GROUP BY (CASE WHEN sender_id = 123 THEN receiver_id 
    ELSE sender_id END); 

SQL fiddle.

+0

@ConradFrix 정확한 최신 날짜를 얻으려면, 나는 그렇게 생각합니다. 나는 그것에 대해 잘못 될 수는 있지만 인라인보기가 없으면 정확한 결과가 나오지 않습니다. –

+1

인라인 뷰가 필요하다고 생각합니다.) 멋진 캐치 –

0

이 당신을 위해 작동합니다 :

SELECT sender_id, receiver_id, message, time FROM your_table GROUP BY sender_id, receiver_id ORDER BY time DESC; 
+1

아닙니다. A에서 B 및 B에서 A로 보내는 메시지는 동일한 스레드입니다. –

0

이 그것을 수행해야합니다

SELECT * FROM (
    SELECT sender_id, receiver_id, 
    IF(sender_id > receiver_id, CONCAT(sender_id, '_', receiver_id), 
    CONCAT(receiver_id, '_', sender_id) 
    ) AS conversation_key, 
    message, `time` 
FROM sms_messages WHERE sender_id = 123 
UNION ALL 
SELECT sender_id, receiver_id, 
    IF(
     sender_id > receiver_id, 
     CONCAT(sender_id, '_', receiver_id), 
    CONCAT(receiver_id, '_', sender_id) 
    ) AS conversation_key, message, `time` 
FROM sms_messages WHERE receiver_id = 123 
) t 
GROUP BY conversation_key ORDER BY NULL 
0

실제로 그것을 테스트하지 않은,하지만 다음 쿼리는 (모두 "방향"에) 모든 별개의 sender_id/receiver_id 조합에 대한 최신 1 메시지를 반환해야합니다

SELECT * 
FROM message m1 
WHERE time = (
    SELECT MAX(time) 
    FROM message m2 
    WHERE 
     (m1.sender_id = m2.sender_id AND m1.receiver_id = m2.receiver_id) 
     OR (m1.sender_id = m2.receiver_id AND m1.receiver_id = m2.sender_id) 
)   

를 일반 영어로 : 선택 모든 메시지는 동일한 발신자/수신자 또는 수신자/발신자에 대한 모든 메시지의 최대 시간을 갖습니다.

원하는 경우, 당신은 쉽게 외부를 개정하여 지정된 사용자에게 그를 제한 할 수 있습니다 WHERE 절, 예를 들어 : 여러 "최신"메시지가있을 수 있음을


1

--- || --- 
AND (sender_id = 123 OR receiver_id = 123) 
time이 고유하지 않은 경우

0

사용자 123은 예일 뿐이므로보다 일반적인 쿼리가 필요하다고 생각합니다. 이 솔루션은 최대 10,000 사용자의 가정 (쉽게 확장 가능)

SELECT sender_id, receiver_id, message, MAX(time), 
IF(sender_id<receiver_id, sender_id*10000+receiver_id, receiver_id*10000+sender_id) as thread_id 
FROM messages 
GROUP BY thread_id 
ORDER BY MAX(time) DESC 
이, 시간 소비 조인 방지

http://sqlfiddle.com/#!2/c65d3/30

UPDATE :

SELECT sender_id, receiver_id, message, MAX(time), 
IF(sender_id<receiver_id, CONCAT(sender_id,receiver_id), CONCAT(receiver_id,sender_id)) as thread_id 
FROM messages 
GROUP BY thread_id 
ORDER BY MAX(time) DESC 
: 이 버전은 사용자 제한 수없는

http://sqlfiddle.com/#!2/c65d3/31

관련 문제