I have a MYSQL ‘activity’ table where all activity by a user gets logged. Let’s say that a user’s activities can be either to ask a question or answer a question. So if a user asks a question, their question gets put into the ‘question’ table and also the activity gets put into the ‘activity’ table. Same thing if user provides an answer, except that the answer goes into the ‘answers’ table and the ‘activity’ table.
The question table’s fields are:
q_id question
The answers table’s fields are:
a_id q_id answer
The activity table’s fields are:
activity_id q_id user_id action_type
(There are more columns then shown above, but these illustrate the point.)
What I want to be able to do is show a user’s recent actions on the site, and actually show what the actions were.
My current MYSQL query simply joins the activity table with the question table as follows (using PDO):
"SELECT *
FROM activity
LEFT JOIN question ON activity.q_id = question.q_id
WHERE activity.user_id = :user_id
ORDER BY activity.a_id desc"
This works okay, and can always give me the question for display in the activities list. However, if the activity that is returned is an answer, I would like to be able to show the answer as well. I tried just using a triple join as follows:
"SELECT *
FROM activity
LEFT JOIN question ON activity.q_id = question.q_id
LEFT JOIN answers ON activity.q_id = answers.q_id
WHERE activity.user_id = :user_id
ORDER BY activity.a_id desc"
But this just gives me a list of rows that is twice as long as the first query, and does not display the answers when the action_type was an answer.
I figure this should be possible, but the more I think about it I believe that maybe I should scrap the activity table and just perform the query directly on the question and answers tables with a UNION? Any opinions on this decision, and any thoughts on the queries?
You could use an outer join, which would return everything in the activity table, even if there isn’t a corresponding row in the answer table:
I’m assuming that for every q_id value in the activity table, there’s always going to be one corresponding row in the question table.
To fix the problem with the duplicate answers, I’d add an a_id field to the activity table. For the question activity, you’d set it to NULL, and for each answer you’d set the a_id field to the appropriate a_id value to identify which answer goes with the activity. You’d then adjust the SQL above as follows: