2013-02-14 9 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 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 

Любые мысли были бы очень оценены.

+1

* Любые мысли? * Вы получаете то, о чем просили. user1 ответил «ДА» на вопрос 1. Пользователь1 не ответил на вопрос 2, поэтому отображается NULL, потому что PA2.text «Нет», но UA2.answer_ID для этого текста является нулевым. Таким образом, вы получаете NULL. Поэтому, если вам нужен список всех вопросов, их возможные ответы и ответ на каждый пользователь. вам нужно начать с вопросов, присоединиться к возможным ответам, а затем присоединиться к ответам пользователей. Правые соединения будут работать в этом месте, но вы должны выяснить правильный порядок. Чтобы на самом деле предоставить ответ, мне нужно знать, какой результат вы хотите. – xQbert

+0

Что такое «группа», намеревающаяся выполнить? – Matthew

+0

@xQbert проблема в том, что эти значения фактически не равны нулю. У пользователя 1 есть ответ на вопрос2. 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 

Возвращает все возможные ответы, ответ любой пользователь предоставил на вопрос, и текст. но он повторяет вопрос/ответы для каждого пользователя.

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. Если порядок важен, то возьмите 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 можно использовать саз (Oracle ДЕКОДИРОВАТЬ, 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

Смежные вопросы