цепочка присоединяется обратно к целевой таблице

#mysql #sql

#mysql #sql

Вопрос:

У меня есть четыре таблицы

 Survey          Question        Responses       Participants
=============   ==============  ==============  =============
id_S            id_Q            id_R            id_P
                id_S            id_Q            id_S
                                id_P
                                id_S
                                Answer
  

Я пытаюсь выяснить, как получить все ответы для участников, которые дали «D» в качестве ответа на вопрос № 3.

Это моя первая попытка, но неудивительно, что это не работает.

 SELECT * 
FROM responses r
LEFT JOIN participants p
ON r.id_P = p.id_P
LEFT JOIN responses r2
ON p.id_R = r.id_P
WHERE r.id_S = 1 AND r2.Answer = "D" AND r2.id_Q = 1
  

By не работает, он возвращает слишком много записей. SQL Select * FROM responses WHERE id_S =1 вернул бы 1891 запись, но вышеупомянутый горячий беспорядок возвращает 15 128 записей.

Очевидно, что у меня даже нет правильного представления о том, как заставить это работать, и это не простая настройка синтаксиса, которая необходима.

Комментарии:

1. Сначала разделите его на два запроса (1) извлеките участников, которые дали «D» в качестве ответа на вопрос № 3, и (2) извлеките все ответы для участников в (1). Идите оттуда

2. почему вы выполняете левое соединение с ответами, почему бы не присоединиться к этому с вопросами?

3. Вы спрашиваете «все ответы для участников», а не «все ответы для участников опроса 1». Я не понимаю, почему прежнее число не может быть больше, чем все ответы в опросе 1.

4. @Oerd можно ли это сделать в одном операторе SQL?

Ответ №1:

 SELECT  ra.*
FROM    responses rd
JOIN    responses ra
ON      (ra.id_s, ra.id_p) = (rd.id_s, rd.id_p)
WHERE   (rd.id_q, rd.answer) = (3, 'D')
  

Комментарии:

1. Интересно, раньше не видел такой формы выражения. Как это называется, чтобы я мог поискать больше, чтобы прочитать об этом?

2. @Erics: о чем именно вы говорите?

3. (name1, name2) = (value1, value2)

Ответ №2:

Попробуйте это:

 SELECT r2.* 
FROM Responses r2
     INNER JOIN (Responses r
     INNER JOIN Question q ON r.id_Q = q.id_Q
     INNER JOIN Participants p ON p.id_P = r.id_P) r1 ON r2.id_P = r1.id_P
WHERE q.id_Q = 3
AND r.Answer = 'D';
  

Комментарии:

1. Я попробую, спасибо. В чем же здесь основная идея?