Как получить все дочерние записи в иерархических данных MYSQL
У меня есть таблица со следующими столбцами
id | parent_customer_id
-----------------------------
1 | 0
2 | 0
3 | 1
4 | 2
5 | 4
6 | 4
Я хотел бы сценарий, который может вернуть все дочерние идентификаторы определенного клиента. Например
get_child_ids (1) = 1,3
get_child_ids(2) = 2,4,5,6
get_child_ids(3) = 3
get_child_ids(4) = 4,5,6
get_child_ids(5) = 5
get_child_ids(6) = 6
Некоторые идентификаторы могут доходить до 10 уровней. Я нашел отличное решение для получения родительских идентификаторов на https://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/ но у меня возникли проблемы получать детей
2 ответа
Лучшее решение - "написать рекурсивный запрос SQL с синтаксисом CTE", но это не поддерживается до MySQL 8.0.1.
Рекурсивный синтаксис CTE - это стандартный SQL, поддерживаемый всеми популярными брендами SQL-совместимых продуктов, теперь, когда MySQL его поддерживает.
Я сделал презентацию о предстоящей функции рекурсивных запросов в MySQL на конференции Percona Live Conference в апреле 2017 года: Рекурсивный сброс запросов в MySQL 8.
WITH RECURSIVE MyCTE AS (
SELECT id, parent_customer_id FROM MyTable WHERE id = ?
UNION
SELECT id, parent_customer_id FROM MyTable JOIN MyCTE
ON MyTable.parent_customer_id = MyCTE.id
)
SELECT * FROM MyCTE;
Если вы не можете использовать MySQL 8.0.1 или новее, вы можете использовать умное решение в ExplainExtended или вы можете хранить свои иерархические данные другим способом для поддержки нерекурсивных запросов.
Я показываю несколько решений в своей презентации Модели для иерархических данных или в своем ответе на вопрос " Какой самый эффективный / элегантный способ разбить плоский стол на дерево?,
Я также написал главу об этом в своей книге " Антипаттерны SQL: предотвращение ловушек программирования баз данных".
Вы должны проверить следующую статью об управлении иерархическими данными в MySQL
Это отличная статья, которая показывает вам отличную технику работы с иерархическими данными с "бесконечной" глубиной.
Слово предостережения: Если вы имеете дело с иерархическими данными, в которых у ребенка есть уникальный родитель, это отличное решение для вас. Но если вы имеете дело с детьми, у которых более одного родителя, то вы имеете дело с графиками, и по этой причине MySQL вам не подходит. Вместо этого вы должны исследовать решения как Neo4J.