2011-08-05 3 views
6

나는 다음과 같이 MYSQL 테이블을 가지고있다.복잡한 조인 쿼리

user TABLE {id INT} 

profile TABLE {user_id INT, facebook_id varchar(50)} 

messages TABLE {id INT, message TEXT, from_id INT, type enum('main','facebook'} 

messages_to TABLE {user_id varchar(50), message_id INT} 

profile.user_id REFERS To user.id 
- the messages_to.message_id refers to the messages.ID column. 
- the messages_to.user_id refers to profile.user_id IF messages.type = 'main' BUT 
    if message_type = 'facebook' THEN messages_to.user_id REFERS to profile.facebook_id 

기본적으로 특정 사람에게 모든 메시지를 선택하는 가입 쿼리를 원한다.하지만 문제는 messages_to.user_id는 the person's facebook ID or the person's ID (a reference to user.id column).

을 참조 할 수있다. 기본적으로 쿼리는 다음과 같이 작동해야합니다.

  • 메시지 테이블의 모든 메시지를 선택하고 messages.type = 'facebook'이 messages_to.user_id가 사람의 FACEBOOK ID와 같은지 확인합니다. (messages_to 테이블은 각 메시지 ID에 대한 수신자를 저장합니다.)
  • messages.type = 'main' messages.type = 'main'person's USER ID (USER.id)

과 같은지 확인하면 messages.type = 'main'를 효율적으로 수행 할 수 있습니까?

messages_tos 테이블은 각 메시지의 모든 수신자를 MESSAGES 테이블에 저장합니다. 메시지에 대한 수신자가 한 명 이상일 수 있습니다.

+2

facebook_id를 저장하려면 별도의 테이블이 필요합니까? 어째서 User 테이블에 facebook_id 필드가 있는지는 null이거나 값을 가질 수 있습니다. 누군가 페이스 북을 통해 계정을 생성 할 때마다 임의의 사용자 이름 (또는 페이스 북의 전자 메일 사용)과 임의의 암호로 사용자를 생성합니다. 그렇다면 항상 user_id를 사용할 수 있으며 페이스 북 사용자가있는 경우 먼저 해당 user_id를 확인하십시오. – mkk

답변

2

나는 이것이 쿼리라고 생각한다.

SELECT messages.*,profile.* 
FROM messages 
JOIN messages_to ON messages.id = messages_to.message_id 
JOIN profile ON 
    (profile.user_id = messages_to.user_id AND messages.type = 'main') 
    OR (profile.facebook_id = messages_to.user_id AND messages.type = 'facebook') 
1

그런 식으로 뭔가요?

select m.*, u.* 
from messages m 
inner join messages_to mt 
on m.id = mt.message_id 
left join profile p 
on (m.type = 'facebook' and mt.user_id = p.facebook_id) 
    or (m.type = 'main' and mt.user_id = p.user_id) 
left join users u 
on p.user_id = u.id 

왜 당신은 당신의 messagesmessages_to 테이블을 분할하고 이것에 대한 하나의 테이블을 사용하지 않는해야합니까? (나는 1 : 1의 관계를 가정하고 있음)

+0

메시지를받는 사람이 1 명 이상인 것으로 생각합니다. – ace

+0

ace : hm, 의미가 있습니다. :) 그렇지만 표의 이름을 '수신자'로 바꿉니다. – knittl

+0

예, 이것이 가장 좋은 용어 일 것입니다. – ace