2013-02-14 3 views
0

J'ai un tableau de réponses qui énumère les réponses possibles pour une question donnée.Gauche Rejoindre plusieurs ensembles de tables

possible_answer 
id question_id text 
1 1   yes 
2 1   no 
3 2   red 
4 2   blue 
5 2   green 

J'ai une table de réponses que les utilisateurs ont donné

user_answer 
id user_id answer_id 
1 10  1 
2 10  3 
3 11  1 
4 11  4 
5 12  2 
6 12  5 

Je suis en train de créer une requête MySQL qui me montrera le nom d'utilisateur, la réponse de l'utilisateur pour la question 1 (pourrait être nulle) et la réponse de l'utilisateur pour la question 2 (pourrait être nulle). Je suis coincé parce que j'ai l'impression de devoir regrouper plusieurs JOINTES GAUCHES ensemble, mais je reçois un résultat qui me donne l'une des réponses, ou la même réponse dans les deux colonnes.

Voici ce que j'ai à ce moment:

SELECT u.name, pa1.text, pa2.text 
FROM user u 
LEFT JOIN user_answer ua1 ON u.id = ua1.user_id 
LEFT JOIN possible_answer pa1 ON ua1.answer_id = pa1.id AND pa1.question_id = 1 
LEFT JOIN user_answer ua2 ON u.id = ua2.user_id 
LEFT JOIN possible_answer pa2 ON ua2.answer_id = pa2.id AND pa2.question_id = 2 
GROUP BY u.id; 

Je recevais des résultats tels que:

username pa1.text pa2.text 
user1  yes  NULL 
user2  no  NULL 
user3  NULL  blue 

Quand je sais qu'il ya des entrées pour les deux questions pour l'utilisateur donné.

je l'group by là-dedans parce que quand je n'avais pas group by je recevais des résultats comme celui-ci (ce qui est sorta plus proche du résultat escompté) mais ils n'apparaissaient pas montrer tout type de modèle:

username pa1.text pa2.text 
    user1  yes  NULL 
    user1  NULL  red 
    user2  no  NULL 
    user2  NULL  NULL 
    user3  no  NULL 
    user3  NULL  blue 

Toutes les pensées seraient très appréciées.

+1

* Des idées? * Vous obtenez ce que vous avez demandé. user1 a répondu "YES" à la question 1. User1 n'a pas répondu à la question 2, NULL est donc affiché car PA2.text est "No" mais UA2.answer_ID est nul pour ce texte. Ainsi vous obtenez NULL. Donc, si vous êtes après une liste de toutes les questions, leurs réponses possibles et quelle réponse fournie par chaque utilisateur. vous devez commencer avec des questions, gauche rejoindre des réponses possibles, puis gauche rejoindre les réponses des utilisateurs. Les jointures droites fonctionneraient dans cet endroit pour mais vous devez déterminer le bon ordre. Pour réellement fournir une réponse, j'ai besoin de savoir quelle sortie vous voulez. – xQbert

+0

À quoi sert le «groupe par»? – Matthew

+0

@xQbert le problème est que ces valeurs ne sont pas réellement nulles. User1 a une réponse à la question2. Les valeurs NULL doivent afficher des valeurs car chacun de ces utilisateurs, dans cet exemple, a répondu aux deux questions. (bien que les fausses données que je montre ne reflètent pas vraiment cela) – Chris

Répondre

0

Voici ce qui a fini par fonctionner.

SELECT DISTINCT u.name, 

(SELECT pa1.text FROM possible_answer pa1, user_answer ua WHERE ua1.user_id = u.id AND ua1.answer_id = pa1.id AND pa1.question_id = 1 ORDER BY ua1.id DESC LIMIT 1) as 'Question1', 

(SELECT pa2.text FROM possible_answer aa2, user_answer ua2 WHERE ua2.user_id = u.id AND ua2.answer_id = pa2.id AND pa.question_id = 2 ORDER BY ua.id DESC LIMIT 1) as 'Question2' 

FROM user u 
GROUP BY u.id; 
0

Peut-être est plus proche de ce que votre après ...

Select UA.User_ID, PA.Question_ID, UA.Answer_ID, PA.Text 
FROM Possible_Answer PA 
LEFT JOIN user_Answer UA on PA.ID = UA.Answer_ID 
ORDER BY PA.Question_ID, UA.User_ID 

Retourne toutes les réponses possibles, la réponse à tout utilisateur a fourni à une question, et le texte. mais il répète des questions/réponses pour chaque utilisateur.

0

S'il n'y a que deux possibilités, vous pouvez utiliser cette astuce:

select ua.user_id, 
     min(pa.text) as answer1, 
     (case when min(pa.text) <> max(pa.text) then max(pa.text) end) as answer2 
from possible_answer pa join 
    user_answer ua 
    on pa.id = ua.answer_id 
group by ua.user_id 

Ce perd la commande en fonction de l'identifiant dans user_answer. Si la commande est importante, alors prenez min(id) et max(id) et retournez à possible_answer pour obtenir les bonnes valeurs.

0

Je sais ce qui est plus d'un hack mais peut-être cela fonctionnerait dans une requête dynamique:

select z.username, w.text as PA1, x.text as PA2 
from user z 
join 
    (select a.user_id, b.question_id, b.text, a.answer_id 
    from 
    user_answer a join possible_answer b on a.answer_id=b.id) as w 
    on w.user_id=z.user_id 
    and w.question_id=1 

join 
    (select a.user_id, b.question_id, b.text, a.answer_id 
    from 
    user_answer a join possible_answer b on a.answer_id=b.id) as x 
    on x.user_id=z.user_id 
    and x.question_id=2 
0

Je travaille avec SQL Server pour écrire de requête avec la syntaxe du serveur SQL. Mais je suis sûr que la même requête fonctionnera aussi dans MySQL (peut-être avec quelques changements).

Pour obtenir des résultats comme vous voulez, vous devez transformer les données de lignes en colonnes. Dans SQL Server, vous pouvez utiliser instruction CASE (Oracle DECODE, MySQL ne sais pas, mais CASE trop peut-être)

Query est

SELECT u.Name, 
MAX(CASE WHEN pa1.QuestionID=1 THEN pa1.Text ELSE NULL END) AS Question1_answer, 
MAX(CASE WHEN pa1.QuestionID=2 THEN pa1.Text ELSE NULL END) AS Question2_answer 
FROM Users u 
LEFT JOIN UserAnswers ua1 ON ua1.UserID=u.ID 
LEFT JOIN PossibleAnswers pa1 ON pa1.ID=ua1.AnswerID 
GROUP BY u.Name 

GROUPEMENT Par nom parce que nous voulons des questions dans une rangée, donc avec le regroupement par Nom et ajouter

MAX(...) 

à des colonnes de réponse que nous réponses de groupe d'un utilisateur dans une ligne

Voici un lien à SqlFiddler où j'ai essayé de créer une même situation http://sqlfiddle.com/#!3/b2357/10