Home > Mobile >  Multiple joined tables and conditions
Multiple joined tables and conditions

Time:01-18

I have the following tables structure:

users
 - id int(PK)
 - role varchar(20)

questions
 - id int (PK)
 - status varchar(20)

answers
 - id int (PK)
 - question_id int (refs questions id)
 - user_id int (refs users id)
 - created_at timestamp

My goal would be to get those questions where the status is 'opened', the last (based on created at) answer is made by a user whose role is admin and the last answer made by a user (non-admin) was at least 1 week ago.

I came up with a veeery long query, most of it works, but the problem is that if there is an answer by a user that is not the last but was at least 1 week ago, it triggers as well.

I'm also opened to simplify my query to remove that bunch of inner joins...

select distinct q.* from questions q 
inner join answers a on a.question_id = q.id
inner join answers a2 on a.question_id = q.id
inner join users u ON u.id = a.user_id
WHERE q.status = 'opened' AND u.role = 'admin' 
and a.id in (select a3.id from answers a3 inner join questions q2 on q.id = a3.ticket_id inner join users u on u.id = a3.user_id where u."role" = 'admin' and a3.created_at = (select max(a3.created_at) from "answers" a3 where a3.question_id = q2.id))
and a2.id in (select a.id from "answers" a
inner join users u on u.id = a.user_id 
where u."role" = 'user'
and a.created_at < (SELECT now() - interval '1 week'))

CodePudding user response:

You are joining the answers table twice without filtering it. You can solve this by using subqueries, something like this:

SELECT questions.*
FROM questions
JOIN (
  SELECT question_id, MAX(created_at) AS max_created_at
  FROM answers
  WHERE user_id IN (SELECT id FROM users WHERE role = 'admin')
  GROUP BY question_id
) admin_answers ON questions.id = admin_answers.question_id
JOIN (
  SELECT question_id, MAX(created_at) AS max_created_at
  FROM answers
  WHERE user_id NOT IN (SELECT id FROM users WHERE role = 'admin')
  GROUP BY question_id
) nonadmin_answers ON questions.id = nonadmin_answers.question_id
WHERE questions.status = 'opened'
AND admin_answers.max_created_at = (SELECT MAX(created_at) FROM answers WHERE question_id = questions.id)
AND nonadmin_answers.max_created_at <= NOW() - INTERVAL '1 week'

If not working give me some sample data for the tables and the expected result and will check it

  • Related