2011-08-05 9 views
6

Je tables MYSQL comme suitcomplexe requête de jointure

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 

Je veux faire une requête de jointure qui sélectionne essentiellement tous les messages à une personne, mais la chose est le messages_to.user_id peut se référer soit the person's facebook ID or the person's ID (a reference to user.id column).

donc, fondamentalement, la requête doit fonctionner comme suit

  • il faut sélectionner tous les messages dans le tableau des messages, et si messages.type = 'facebook' vérifie si messages_to.user_id e quals FACEBOOK ID de la personne. (Noter que les magasins de table de messages_to les destinataires pour chaque message ID)
  • mais si les messages.type = 'main' vérifie si le messages_to.user_id est égal à la person's USER ID (USER.id)

Est-il possible de faire un mysql join query pour cela efficacement?

La table messages_tos stocke TOUS les destinataires pour chaque message dans la table MESSAGES. IL PEUT Y AVOIR PLUS D'UN DESTINATAIRE pour un message.

+2

Êtes-vous sûr de vouloir utiliser une table séparée pour stocker facebook_id? Que diriez-vous d'avoir dans la table utilisateur un champ facebook_id, qui peut être soit nul ou a une valeur. Chaque fois que quelqu'un crée un compte via facebook, vous créez un utilisateur à la volée avec un nom d'utilisateur aléatoire (ou utilisez l'adresse e-mail de facebook) et un mot de passe aléatoire. Ensuite, vous pouvez toujours utiliser user_id et si vous avez un utilisateur facebook, vous vérifiez d'abord l'ID utilisateur correspondant – mkk

Répondre

2

Je suppose que c'est la requête.

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

quelque chose comme ça?

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 

pourquoi avez-vous vos messages et messages_to tables se séparent et ne pas utiliser une seule table pour cela? (Je suppose une relation 1: 1)

+0

Je pense que c'est pour que les messages aient 1 ou plusieurs destinataires. – ace

+0

ace: hm, a du sens :) mais alors je renomme la table en 'destinataires ' – knittl

+0

oui, je crois que ce serait le meilleur terme. – ace