Нет, запрос сделан неправильно! Он, дополнительно к тому, что требуется, выберет еще и пользователей, которые
написали комментарий, даже если их собственные статьи никто не комментировал... не говоря уже о том, что если нет явной необходимости аггрегирования полей в группе, то использование GROUP BY там, где можно обойтись DISTINCT - дорогое удовольствие (почему - объясню дальше, а пока, просто для сравнения, его план и "стоимость"):
![5ab3f036b072d356066942.png](https://habrastorage.org/webt/5a/b3/f0/5ab3f036b072d356066942.png)
Чтобы просто получить нужный результат, его, конечно, можно тупо дополнить еще одним JOIN с
article_comment_association, но это все еще очень плохо: во-первых, JOIN с таблицей комментариев там просто лишний, во-вторых, GROUP BY - все то же разбазаривание ресурсов:
![5ab3f0802b299318193006.png](https://habrastorage.org/webt/5a/b3/f0/5ab3f0802b299318193006.png)
Вот, для сравнения, стоимость DISTINCT vs. GROUP BY:
![5ab3f08c07b85920446589.png](https://habrastorage.org/webt/5a/b3/f0/5ab3f08c07b85920446589.png)
(Все эти неправильные варианты приводить не буду, чтоб их случайно не скопипейстили в систему управления ядерным реактором!)
В этом смысле вариант, предложеный
Rsa97 , уже лучше, т.к. дает правильный результат.
SELECT name FROM users
WHERE id IN (
SELECT user_id FROM article
WHERE id IN (
SELECT article_id FROM article_comment_association
)
);
Однако, использование subquery в таком порядке, действительно, не позволяет использовать distinct:
![5ab3f109468d6235394789.png](https://habrastorage.org/webt/5a/b3/f1/5ab3f109468d6235394789.png)
Фишка в том, что subquery, как правило, создают временную таблицу, обычно, в памяти, но если ее мало, то и на диске. Так что, если есть возможность заменить их на JOIN (а она есть почти всегда!), это нужно делать, не стесняясь.
А вот феншуйная (она же - правильная, легко читаемая, очевидная и эффективная) версия запроса:
SELECT distinct users.name from users
INNER JOIN article ON (article.user_id = users.id)
INNER JOIN article_comment_association ON (article.id = article_comment_association.article_id)
... и ее план:
![5ab3f135365b0576447042.png](https://habrastorage.org/webt/5a/b3/f1/5ab3f135365b0576447042.png)
Мораль истории: в реляционной базе данных самый прямой путь к нужному результату, как правило, оказывается наиболее эффективным. Как общее правило - начинать нужно с самого большого множества записей, исключая за раз как можно больше ненужного, и давая оптимизатору использовать индексы.