Reputation: 13
Feel like this should be a rather simple problem yet, I'm struggling to find the solution.
We have three tables to create a Question Answer system. One is the question, other is answer and then the third is finally where we store the user's selection.
Question table
QuestionID Question
1 What is your favorite color?
2 Where were you born?
Answer table
AnswerID QuestionID Answer
1 1 Blue
2 1 Green
3 1 Yellow
4 2 USA
5 2 Africa
Answer stored table
AnswerStoreID QuestionID AnswerID UserID
1 1 1 1
2 1 2 1
3 2 4 2
4 2 5 2
5 1 1 3
I want to find the UserID that answered QuestionID 1 as AnswerID 1 AND QuestionID 2 as AnswerID 4.
Thought it would be simple like this
SELECT UserID
FROM Question Q
INNER JOIN Answer A ON A.QuestionID = A.QuestionID
INNER JOIN AnswerStore AS ON AS.AnswerID = A.AnswerID
WHERE (AS.AnswerID = 1 AND AS.QuestionID = 1)
AND (AS.AnswerID = 2 AND AS.QuestionID = 4)
That renders nothing though. When replacing the AND
between the two where statements with an OR
gets results that don't have both those answers though which is not desired either. I want only those users who answered both of these questions.
I then did a query with some various joins to do a query per question but feel that is too complicated and heavy for this problem and I'm overthinking it. Is there an easier solution to this problem?
Upvotes: 0
Views: 34
Reputation: 189
You are really looking at two sets of data, UserIDs that answered QuestionID 1 as AnswerID 1, and UserIDs that answered QuestionID 2 as AnswerID 4. So you can join the sets together to find UserIDs that are in both sets of data:
SELECT UserID
FROM AnswerStore as1 INNER JOIN AnswerStore as2 ON as1.UserID = as2.UserID
AND as1.QuestionID = 1 AND as1.AnswerID = 1
AND as2.QuestionID = 2 AND as2.AnswerID = 4
Upvotes: 0
Reputation: 15951
---- Edit ----
Actually, you don't even need the JOINs in your original query:
SELECT t.UserID
FROM AnswerStore AS t
WHERE (t.AnswerID = 1 AND t.QuestionID = 1)
OR (t.AnswerID = 2 AND t.QuestionID = 4)
GROUP BY t.UserID
HAVING COUNT(*) = 2
---- Original Full Answer ----
This is actually a fairly common question, that appears a couple times a week. Unfortunately, it is really hard to formulate a repeatable/searchable question to reference for it.
SELECT UserID
FROM Question Q
INNER JOIN Answer A ON A.QuestionID = A.QuestionID
INNER JOIN AnswerStore AS ON AS.AnswerID = A.AnswerID
WHERE (AS.AnswerID = 1 AND AS.QuestionID = 1)
OR (AS.AnswerID = 2 AND AS.QuestionID = 4)
GROUP BY UserID
HAVING COUNT(*) = 2
The general form is:
SELECT A.a_id
FROM A
INNER JOIN B ON A.a_id = B.a_id
WHERE B.something IN ([list])
GROUP BY a_id
HAVING COUNT(*) = [length of list]
-- or in cases where B matches may be non-unique
-- HAVING COUNT(DISTINCT B.something) = [length of list]
Upvotes: 2