2010-01-06 15 views
0

Je sais qu'il doit y avoir un moyen de le faire, mais pour la vie de moi je ne peux pas le comprendre:MySQL Rejoignez plusieurs à plusieurs en tant que lignes simples

J'ai 3 tables Je veux réunir (simplifié pour illustrer):

users 
uid mail 
1 [email protected] 
2 [email protected] 
3 [email protected] 

profile_fields 
fid name  label 
1 full_name Full Name 
2 phone  Phone 

profile_values 
uid fid value 
1 1 Q Q 
1 2 5555555555 
2 1 Ww Ww 
3 2 4444525411 

J'aimerais obtenir des résultats de la forme:

uid mail  full_name phone 
1 [email protected] Q Q  5555555555 
2 [email protected] Ww Ww  NULL 
3 [email protected] NULL  44445454111 

J'ai essayé différentes SELECTs avec différentes conditions REJOIGNEZ mais je ne peux pas à comprendre comment obtenir les lignes de profile_fields mes colonnes dans mon SELECT

EDIT: J'ai également essayé de googler autour, mais je n'arrive pas à comprendre comment faire une phrase pour google.

+0

Mise à jour - lignes manquantes probablement parce que je rejoignais la table 'PROFILE_VALUES' plutôt que LEFT JOINing pour les utilisateurs sans enregistrements dans la table' PROFILE_VALUES'. –

+0

J'ai essayé de faire une jointure à gauche, toujours en ligne. Je vais utiliser comme Views Bonus Pack pour faire au moins ce rapport. –

Répondre

4

Utilisation:

SELECT u.uid, 
     u.mail, 
     MAX(CASE WHEN pf.name = 'full_name' THEN pv.value END) AS full_name, 
     MAX(CASE WHEN pf.name = 'phone' THEN pv.value END) AS phone 
    FROM USERS u 
    LEFT JOIN PROFILE_VALUES pv ON pv.uid = u.uid 
    JOIN PROFILE_FIELDS pf ON pf.fid = pv.fid 
         AND pf.name IN ('full_name', 'phone') 
GROUP BY u.uid, u.mail 
+0

C'est ce que j'avais peur de devoir faire. C'est la vie. Merci! –

+0

Ce _amlost_ fonctionne. Mais je reçois seulement une rangée, pas toutes les rangées. J'ai essayé de tuer les appels MAX(), mais il souffle complètement et me donne une rangée par champ. –

1

Ce que vous essayez de faire est appelé un pivot. MySQL ne supporte pas le pivotement natif, mais vous pouvez le faire en utilisant la requête OMG Ponies publiée. Toutefois, si vous devez prendre en charge un nombre arbitraire de champs de profil, vous devez générer le SQL dynamiquement.

+1

Il est techniquement arbitraire, mais pour mes fins je peux juste maintenir la requête à la main. À l'avenir, je pourrais essayer de trouver un moyen de le faire via une procédure stockée et être capable de générer la requête de façon dynamique. –

0

Je pense qu'en général vous ne pouvez pas faire ce que vous voulez. Même si l'exemple @OMG Ponies est correct, il ne fonctionnera pas pour les autres valeurs des noms de champs profile_.

Vous pouvez essayer d'écrire du code pour générer une requête pour différentes valeurs de profile_fields en fonction des champs profile_fields réels.

Vous pouvez également effectuer une jointure plusieurs-à-plusieurs simple et analyser des données dans un autre programme/code.

+0

Cela aurait fonctionné, mais le problème est que j'utilise la requête SQL pour générer un rapport XLS, donc j'ai besoin d'être en pur SQL. J'étudie en utilisant un module Drupal pour faire ceci, mais je ne suis pas sûr s'il peut exporter en tant que XLS. –