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 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

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

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

任何想法将不胜感激。

4

5 回答 5

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

返回所有可能的答案、任何用户对问题提供的答案以及文本。但它会为每个用户重复问题/答案。

于 2013-02-14T20:16:56.553 回答
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

这会丢失基于 id 的排序user_answer。如果排序很重要,则使用min(id)andmax(id)并返回 topossible_answer以获得正确的值。

于 2013-02-14T20:24:02.733 回答
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
于 2013-02-14T20:52:24.463 回答
0

我正在使用 SQL Server,因此使用 SQL Server 的语法编写查询。但我确信同样的查询也可以在 MySQL 中使用(可能会有一些变化)。

为了获得所需的结果,您需要将行数据转换为列。在 SQL Server 中,您可以使用 CASE 语句(Oracle 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

按名称分组,因为我们希望问题排在一行,所以按名称分组并添加

MAX(...) 

对于答案列,我们将一个用户的答案分组在一行中

这里是 SqlFiddler 的链接,我尝试在其中创建相同的情况 http://sqlfiddle.com/#!3/b2357/10

于 2013-02-14T20:53:25.147 回答
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;
于 2013-03-18T16:05:40.117 回答