Creo que esto debería hacerlo:
UPDATE QandA AS ans1
JOIN QandA AS ans2 ON ans2.related = ans1.related
JOIN QandA AS ques ON ans2.related = ques.id
SET ans1.accepted = (ans1.id = :answer_id)
WHERE ques.author_id = :session_id
AND ans2.id = :answer_id
El primer JOIN
filtra las respuestas a la misma pregunta que la respuesta que se acepta.
El segundo JOIN
encuentra esa pregunta.
El WHERE
La cláusula restringirá la actualización solo a las preguntas con el autor dado y especifica el ID de respuesta que se acepta.
Para la condición adicional, agregue
AND (ques.free IS NULL or ans1.accepted IS NULL)
al WHERE
cláusula. ques.free IS NULL
coincide con cualquier pregunta libre y ans1.accepted IS NULL
coincide con una pregunta sin respuesta aceptada (porque cuando se acepta una respuesta, todas las demás respuestas a esa pregunta obtienen accepted = 0
).
DEMO de pregunta sin respuesta aceptada
DEMO de pregunta que es gratis