Sqlfiddle Solution
Вам нужно использовать WITH RECURSIVE , как предлагает Майк. Его ответ полезен, особенно в отношении использования distinct
для устранения избыточных подсчетов для консультантов, но он не приводит к точным результатам, которые вы ищете.
См. Рабочее решение в sqlfiddle выше . Я считаю, что это именно то, что вы ищете:
WITH RECURSIVE results(skill_id, parent_id, consultant_id)
AS (
SELECT skills.id as skill_id, parent_id, consultant_id
FROM consultant_skills
JOIN skills on skill_id = skills.id
UNION ALL
SELECT skills.id as skill_id, skills.parent_id as parent_id, consultant_id
FROM results
JOIN skills on results.parent_id = skills.id
)
SELECT skill_id, count(distinct consultant_id) from results
GROUP BY skill_id
ORDER BY skill_id
В запросе под UNION ALL
происходит то, что мы рекурсивно присоединяем таблицу навыков к самой себе, но меняем предыдущий родительский идентификатор. в качестве нового идентификатора навыка и с использованием нового родительского идентификатора на каждой итерации. Рекурсия останавливается, потому что в конечном итоге родительский идентификатор равен NULL, и нет JOIN, потому что это INNER-соединение. Надеюсь, это имеет смысл.