2013-02-14 153 views
0

我有一个答案表,列出了给定问题的可能答案。左连接多组表格

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

然后,我有用户给

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 

我想创建一个MySQL查询,将显示我的用户名答案的表,用户的问题1回答(可能为空)和用户对问题2的回答(可能为空)。我陷入困境,因为我觉得我需要将多个LEFT JOIN分组在一起,但是我得到的输出给了我一个答案,或者两个列中都有相同的答案。

这里就是我在这一点上有:

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 

当我知道有这两个问题给定用户的条目。

我在那里group by,因为当我没有group by我得到这样的结果(这是八九不离十接近预期的结果),但他们并没有出现显示任何类型的模式:

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

任何想法将不胜感激。

+1

*有什么想法?*你得到你所要求的。 user1对问题1回答“是”。用户1对问题2没有回答,因此显示NULL,因为PA2.text是“否”,但UA2.answer_ID对于该文本为空。因此你得到NULL。因此,如果您要列出所有问题的列表,可能的答案以及每个用户提供的答案。你需要从问题开始,左侧加入可能的答案,然后左侧加入到用户的答案中。在这个地方,右连接可以工作,但你必须找出正确的顺序。要真正提供答案,我需要知道你想要什么输出。 – xQbert 2013-02-14 20:08:32

+0

准备完成的'group by'是什么? – Matthew 2013-02-14 20:10:33

+0

@xQbert问题是这些值实际上不是null。用户1确实有问题2的答案。 NULL应该显示值,因为在这个例子中,每个用户都回答了这两个问题。 (尽管我所展示的假数据可能并不真实反映这一点) – Chris 2013-02-14 20:19:42

回答

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 

返回所有可能的答案,任何用户提供了一个问题的答案,和文本。但它会为每个用户重复提问/回答。

0

如果只有两种可能,你可以使用这一招:

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中的排序。如果订购非常重要,那么请采取min(id)max(id)并返回possible_answer以获得正确的值。

0

我知道这更多的是一种黑客攻击,但也许这将在动态查询工作:

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

我与SQL Server的工作,所以写的查询与SQL Server的语法。但我相信同样的查询也将在MySQL中工作(可能会有一些变化)。

如果您想获得结果,您需要将行数据转换为列。 在SQL Server,你可以使用CASE语句(甲骨文DECODE,MySQL的不知道,但情况下也说不定)

查询

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 

分组依据名称,因为我们希望在一排的问题, 所以用分组通过名称和一行

这里的链接添加

MAX(...) 

一个用户的答案,我们组的答案列到SqlFiddler我试图创建一个相同的情况 http://sqlfiddle.com/#!3/b2357/10