2009-10-19 5 views
1

Cela fonctionne si je supprime la ligne JOIN finale, mais je ne sais pas pourquoi il ne fonctionnera pas avec elle. Les deux dernières instructions JOIN tentent d'extraire des données ('meta_value') de différentes lignes de la même table, dont les noms ne peuvent être trouvés qu'en lisant une autre colonne correspondante ('meta_key') dans la même table. Tout cela en joignant tout sur le user_id commun dans les 3 tables.SQL: joignant 3 tables, ayant besoin de joindre aussi le 3ème à lui-même

SELECT mod_membership.uid, 
     mod_membership.wp_user_id, 
     mod_membership.status, 
     mod_membership.last_login, 
     mod_membership.membership_type, 
     mod_membership.membership_expiration, 
     wp_users.user_login, 
     wpm_a.meta_value AS first_name 
    FROM mod_membership 
    JOIN wp_users ON wp_users.ID = mod_membership.wp_user_id 
    JOIN wp_usermeta AS wpm_a ON wpm_a.user_id = mod_membership.wp_user_id WHERE wpm_a.meta_key = 'first_name' 
    JOIN wp_usermeta AS wpm_b ON wpm_b.user_id = mod_membership.wp_user_id WHERE wpm_b.meta_key = 'last_name' 

Comment puis-je obtenir ce troisième JOIN pour travailler ou utiliser une autre méthode pour obtenir ces résultats dans un seul jeu de résultats, groupés sur user_id?

+0

Je veux juste remercier tout le monde pour ces réponses rapides et des solutions. Vous avez tous été d'une grande aide. – Jeff

Répondre

4

essayez ceci:

SELECT m.uid, m.wp_user_id,m.status, 
    m.last_login,m.membership_type, 
    m.membership_expiration, 
    u.user_login, 
    f.meta_value first_name, 
    l.meta_value last_name 
From mod_membership m 
    Join wp_users u 
     On u.ID = m.wp_user_id 
    Left Join wp_usermeta f 
     On f.user_id = m.wp_user_id 
     And f.meta_key = 'first_name' 
    Left Join wp_usermeta l 
     On l.user_id = m.wp_user_id 
     And l.meta_key = 'last_name' 

Pour répondre à votre question la raison pour laquelle votre syntaxe ne fonctionnait pas est, tout d'abord, il ne peut y avoir qu'une seule clause where par instruction SQL. Vous ne pouvez pas ajouter de clause where pour chaque jointure, c'est la raison pour laquelle la clé "On" est utilisée ...

Ensuite, les conditions de cette clause Where ne sont pas appliquées avant la génération du résultat final, alors que les conditions de jointure sont évalués "en cours de route" à mesure que chaque ensemble de résultats intermédiaire est construit à partir de chaque déclaration de jointure successive.

+0

Ceci est parfait et obtient à la fois le prénom et le nom de famille dans le jeu de résultats. Merci Charles. – Jeff

1

Echange OÙ ET pour

SELECT mod_membership.uid, 

mod_membership.wp_user_id, 

mod_membership.status, 

mod_membership.last_login, 

mod_membership.membership_type, 

mod_membership.membership_expiration, 

wp_users.user_login, 

wpm_a.meta_value AS first_name 

FROM mod_membership 

JOIN wp_users ON wp_users.ID = mod_membership.wp_user_id 

JOIN wp_usermeta AS wpm_a ON wpm_a.user_id = mod_membership.wp_user_id AND wpm_a.meta_key = 'first_name' 

JOIN wp_usermeta AS wpm_b ON wpm_b.user_id = mod_membership.wp_user_id AND wpm_b.meta_key = 'last_name' 
3

Pour autant que je peux dire, vous n'avez pas besoin d'une 3ème rejoindre - il semble que vous essayez de le faire:

SELECT DISTINCT mod_membership.uid, mod_membership.wp_user_id, 
mod_membership.status, mod_membership.last_login, 
mod_membership.membership_type, mod_membership.membership_expiration, 
wp_users.user_login, wpm_a.meta_value AS first_name 

FROM mod_membership 
INNER JOIN wp_users ON wp_users.ID = mod_membership.wp_user_id 
INNER JOIN wp_usermeta AS wpm_a ON wpm_a.user_id = mod_membership.wp_user_id 
WHERE (wpm_a.meta_key = 'first_name' OR wpm_a.meta_key = 'last_name') 

Le raison pour laquelle votre requête d'origine ne fonctionne pas est que vous ne pouvez avoir qu'une seule clause WHERE.

+0

Je pense que vous devriez utiliser 'AND' au lieu de' OR' dans l'instruction 'WHERE'. –

+0

'wpm_a.meta_key = 'first_name' OU wpm_a.meta_key = 'last_name'' signifie que la valeur correspondra - le JOIN dans l'OP signifie que ** LES DEUX ** doivent être présents pour correspondre. –

+0

@ Ivan & @rexem Je ne suis pas sûr que ce soit l'intention de l'OP ... J'attendrai le @Deca pour clarifier avant de modifier. – Greg

Questions connexes