2010-06-17 17 views
2

Je tables comme:Une table, besoin de plusieurs valeurs de différentes lignes/tuples

'profile_values' 
userID | fid  | value 
-------+---------+------- 
1  | 3  | [email protected] 
1  | 45  | 203-234-2345 
3  | 3  | [email protected] 
1  | 45  | 123-456-7890 

Et:

'users' 
userID | name  
-------+------- 
1  | joe  
2  | jane  
3  | jake  

Je veux les rejoindre et ont une ligne avec deux des valeurs telles que :

'profile_values' 
userID | name | email   | phone 
-------+-------+----------------+-------------- 
1  | joe | [email protected] | 203-234-2345 
2  | jane | [email protected] | 123-456-7890 

Je l'ai résolu, mais il se sent maladroit et je veux savoir s'il y a une meilleure façon de le faire. Signifiant des solutions plus lisibles ou plus rapides (optimisées) ou simplement des meilleures pratiques.

solution actuelle: plusieurs tables sélectionnées, de nombreuses déclarations conditionnelles:

SELECT u.userID AS memberid, 
     u.name AS first_name, 
     pv1.value AS fname, 
     pv2.value as lname 
FROM users AS u, 
     profile_values AS pv1, 
     profile_values AS pv2, 
WHERE u.userID = pv1.userID 
    AND pv1.fid = 3 
    AND u.userID = pv2.userID 
    AND pv2.fid = 45; 

Merci pour l'aide!

+0

est-ce que les 2 dernières lignes du premier tableau devraient avoir 2 dans la première colonne? – potatopeelings

+0

Je veux juste combiner une table d'utilisateur qui a beaucoup plus de valeurs appartenant à cet utilisateur dans une rangée. Mais ces autres valeurs existent dans plusieurs lignes dans une seule table. Donc en combinant cela dans une table avec les valeurs dans une rangée. Le profil utilisateur du module Drupal fonctionne de cette façon lorsqu'il ajoute des fonctionnalités pour étendre les valeurs du profil utilisateur. – JeroenEijkhof

Répondre

4

Il est une question de pivot typique:

SELECT u.userid, 
     u.name, 
     MAX(CASE WHEN pv.fid = 3 THEN pv.value ELSE NULL END) AS email, 
     MAX(CASE WHEN pv.fid = 45 THEN pv.value ELSE NULL END) AS phone, 
    FROM USERS u 
    JOIN PROFILE_VALUES pv ON pv.userid = u.userid 
GROUP BY u.userid, u.name 

Ajouter « GAUCHE » avant le « JOIN » si vous voulez voir les utilisateurs qui ne sont pas des entrées de la table PROFILE_VALUES.

+0

Cela m'a seulement retourné une rangée, quand ma table d'utilisateurs est en réalité 442 tuples gros. Peut-être que je fais quelque chose de mal ... En fait, il ne me donne que la première ligne de ma table d'utilisateurs associée aux valeurs de ma table profile_values ​​ – JeroenEijkhof

+0

@WmasterJ: Les 441 autres utilisateurs ont-ils des entrées dans la table 'PROFILE_VALUES'? Je suis prêt à parier qu'ils ne le font pas - voir ma note sur l'utilisation d'un jointure à gauche dans ce cas. –

+0

@Ponies: Merci d'avoir répondu si vite. Oui, ils ont des entrées. Dans mon autre SQL que je cours et qui est inclus dans ma question, je n'ai que 220 lignes parce que ce sont les seules qui ont les valeurs que je recherche. J'ai vu le commentaire LEFT JOIN, n'a pas fonctionné. Mon instruction sql est un peu différente puisque j'ai utilisé un exemple ici. Mais si vous pouvez trouver quelque chose de mal dans ce SQL: http://piratepad.net/Io1HDPFHJi – JeroenEijkhof

0

Je n'ai pas dit cela, ce que je devrais avoir (@OMG Ponies) mais je voulais l'utiliser dans une vue MySQL. Et pour que les vues soient éditables, vous n'êtes pas autorisé à utiliser les fonctions d'agrégat et other constraints. Donc ce que j'ai dû faire, c'est utiliser la même requête SQL que celle que j'avais décrite dans la question initiale.

Espérons que cela aide quelqu'un, en ajoutant une balise pour créer des vues.