Reputation: 189
Here's the structure of my database (used to collect info from a survey):
question_responses->answer_choices->subquestions->questions->survey
| ^
V |
submissions->response_group<----------------------------survey_deployment
where A->B means A has the PK of B
So, I want to get the responses of a particular user; let's say that his submission pk is 1. I had written the query
select question_responses.answer_text
from submissions join question_responses on (question_responses.submission_pk = submission.pk)
join answer_choices on (question_responses.answer_choices_pk = answer_choices.pk)
join subquestions on (answer_choices.subquestions_pk = subquestions.pk)
right join questions on (subquestions.questions_pk = questions.pk)
where submissions.pk = 1
order by questions.order
It is possible to not answer questions. In such a case, there is no question_responses.pk recorded. I would still like to be able to account for skipping, so I need this record to be returned, even if there is no response. I thought that the right join
would have accounted for this record, but apparently not.
Any help is greatly appreciated.
Upvotes: 0
Views: 57
Reputation: 69819
Because you have submissions.pk = 1
in the where clause this effectively turns your outer join into an inner join, since any missing submission will have a pk of null. and null = 1
is not true.
You could rewrite your query using a LEFT JOIN, and selecting from questions:
select question_responses.answer_text
from questions
left join (subquestions
inner join answer_choices
on answer_choices.subquestions_pk = subquestions.pk
inner join question_responses
on question_responses.answer_choices_pk = answer_choices.pk
inner join submissions
on question_responses.submission_pk = submission.pk)
on subquestions.questions_pk = questions.pk
and submissions.pk = 1
order by questions.order;
This is similar to doing something like:
select subquery.answer_text
from questions
left join
( select question_responses.answer_text, subquestions.questions_pk
from subquestions
inner join answer_choices
on answer_choices.subquestions_pk = subquestions.pk
inner join question_responses
on question_responses.answer_choices_pk = answer_choices.pk
inner join submissions
on question_responses.submission_pk = submission.pk
where submissions.pk = 1
) subquery
on subquery.questions_pk = questions.pk
order by questions.order;
but depending on your dbms the former may perform better as it has no derived tables.
Upvotes: 1
Reputation: 277
Check out this, does it help?
SELECT question_responses.answer_text
FROM questions LEFT JOIN subquestions on (subquestions.questions_pk = questions.pk)
LEFT JOIN answer_choices on (answer_choices.subquestions_pk = subquestions.pk)
LEFT JOIN question_responses on (question_responses.answer_choices_pk = answer_choices.pk)
LEFT JOIN submissions on (question_responses.submission_pk = submission.pk)
WHERE submissions.pk = 1
ORDER BY questions.order
Upvotes: 0