PHP + MySQLi - не знаю, как запросить БД для решения моей проблемы - PullRequest
0 голосов
/ 01 августа 2020

У меня есть следующая MySQLi-DB:


    ╔═════════════╦═══════════╦════════════════╗
    ║ category_id ║ parent_id ║ name           ║
    ╠═════════════╬═══════════╬════════════════╣
    ║ 28          ║ 1         ║ blog root      ║
    ╠═════════════╬═══════════╬════════════════╣
    ║ 30          ║ 28        ║ painting       ║
    ╠═════════════╬═══════════╬════════════════╣
    ║ 31          ║ 30        ║ kids painting  ║
    ╠═════════════╬═══════════╬════════════════╣
    ║ 32          ║ 30        ║ teens painting ║
    ╠═════════════╬═══════════╬════════════════╣
    ║ 35          ║ 28        ║ recipes        ║
    ╠═════════════╬═══════════╬════════════════╣
    ║ 36          ║ 28        ║ diy            ║
    ╚═════════════╩═══════════╩════════════════╝

Это дерево категорий


    blog root
        painting
            kids painting
            teens painting
        recipes
        diy

Мне нужно создать запрос, который приведет ко всем category_id для категории с все его подкатегории.

ПРИМЕР:

1) query with category_id = 30 --> result 30, 31, 32
2) query with category_id = 28 --> result 28, 30, 31, 32, 35, 36
3) query with category_id = 35 --> result 35

Мой запрос newbe:

SELECT `category_id` FROM `blog_category` WHERE `category_id` = 28 OR `parent_id` = 28

это приведет к 28, 30, 35, 36 -> отсутствует 31 , 32

Как я могу решить эту проблему?

Изменить: в MySQL невозможно, как кажется.

Итак, как я могу создать с PHP и easy Mysql - запрашивает строку с разделителями-запятыми для выполнения окончательного запроса, такого как , это решение в stackoverflow ?

--->

... WHERE category_id IN ('$string')

1 Ответ

1 голос
/ 01 августа 2020

Обычно вы используете рекурсивный запрос для обхода иерархического дерева. Эта функция доступна только в MySQL 8.0:

with recursive cte as (
    select category_id, parent_id, name, 1 lvl from mytable where category_id = 28
    union all
    select t.category_id, t.parent_id, t.name, c.lvl + 1
    from cte c
    inner join mytable t on t.parent_id = c.category_id
)
select * from cte order by lvl, category_id

Это дает вам одну строку для каждого дочернего элемента, упорядоченную по возрастанию глубины, а затем по category_id.

Если вам нужна запятая разделенное значение вместо набора строк, тогда вы можете просто изменить последнюю часть запроса, чтобы использовать агрегирование:

select group_concat(category_id order by lvl, category_id) all_category_ids
from cte
...