2013-02-14 5 views
0

주어진 질문에 대한 가능한 대답을 나열한 응답 표가 있습니다. 그런 다음여러 테이블 조인 왼쪽 왼쪽

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

I 사용자가 내가 나에게 사용자 이름을 표시합니다 MySQL의 쿼리를 만들려고하고

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 

준 답변의 테이블을 가지고, 질문 1에 대한 사용자의 대답은 (null이 될 수 있습니다) 및 질문 2에 대한 사용자의 대답 (null 일 수 있음)이 표시됩니다. 여러 개의 LEFT JOINS를 함께 그룹화해야 할 필요가 있다고 느껴지기 때문에 멈추고 있습니다. 그러나 출력 중 하나를 제공하거나 두 열 모두에서 동일한 대답을 얻습니다.

여기에 나는이 점에있어 무엇 : 같은

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; 

내가 무엇입니까 결과 :

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

나는 주어진 사용자에 대한 두 질문에 대한 항목이 있다는 것을 알게되면.

username pa1.text pa2.text 
    user1  yes  NULL 
    user1  NULL  red 
    user2  no  NULL 
    user2  NULL  NULL 
    user3  no  NULL 
    user3  NULL  blue 
: 나는 (의도 된 결과에 그렇다고 가까운)이 같은 결과를 얻고 있었다 group by을 가지고 있지 않았지만 그들은 패턴의 모든 종류를 표시하는 표시되지 않은 경우 때문에

는 내가 거기에 group by

의견을 보내 주시면 감사하겠습니다.

+1

* 어떤 생각을 했습니까? user1은 질문 1에 "예"라고 대답했습니다. User1은 질문 2에 대한 응답이 없으므로 PA2.text가 "아니요"이지만 UA2.answer_ID는 해당 텍스트에 대해 NULL이므로 NULL이 표시됩니다. 따라서 당신은 NULL을 얻습니다. 따라서 모든 질문의 목록, 가능한 대답 및 각 사용자가 제공 한 답변에 대해 알고 있다면 당신은 질문으로 시작, 가능한 답변에 가입을 왼쪽, 그리고 나서 사용자 답변에 왼쪽으로 가입해야합니다. 오른쪽 조인은이 위치에서 작동하지만 올바른 순서를 알아 내야합니다. 실제로 답변을 제공하려면 원하는 출력을 알아야합니다. – xQbert

+0

달성하려는 '그룹'은 무엇입니까? – Matthew

+0

@xQbert 문제는 ​​그 값이 실제로 null이 아니라는 것입니다. User1은 question2에 대한 답변을 가지고 있습니다. 이 예에서 각 사용자가 두 질문에 모두 응답했기 때문에 NULL이 값을 표시해야합니다. (내가 보여주고있는 가짜 데이터가 실제로 반영되지는 않았을지라도) – Chris

답변

0

다음은 작동이 끝난 것입니다.

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

어쩌면이 무엇을 당신의 후에 가까운 ...

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 

반환 가능한 모든 답변, 모든 사용자가 질문에 제공 한 응답, 텍스트. 각 사용자에 대해 질문/답변을 반복합니다.

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 

user_answer의 ID를 기반으로 순서를 잃는다 :

0

오직 두 가지 가능성이있는 경우,이 트릭을 사용할 수 있습니다. 주문이 중요한 경우 min(id)max(id)을 가져오고 possible_answer에 다시 가입하면 올바른 값을 얻을 수 있습니다.

0

나는이 해킹의 더 알고하지만 어쩌면이 동적 쿼리에서 일 것이다 : 나는 SQL 서버의 구문 쿼리 쓰기 때문에 SQL 서버 함께 일하고

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

. 그러나 나는 같은 쿼리가 MySQL에서도 작동 할 것이라고 확신한다 (약간의 변경이있을 수 있음).

원하는대로 결과를 얻으려면 행 데이터를 열로 변환해야합니다.SQL의 당신이 CASE 문을 사용하여 서버 (오라클 DECODE, MySQL은 확실하지하지만 너무 어쩌면 CASE)에서

쿼리는 우리가 한 행에서 질문을 원하기 때문에 이름으로

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 

GROUPING이다 그래서 그룹으로하여 이름을 지정하고 여기에 하나의 행

링크에서 하나의 사용자의 응답 우리 그룹의 답변의 열을

MAX(...) 

추가 동일한 상황을 만들려고했던 SqlFiddler에게 http://sqlfiddle.com/#!3/b2357/10