MySQL — Как получить доступ ко всем узлам на уровне 2 в таблице

Я создаю базу данных для сайта электронной коммерции, которая имеет вложенные категории, и я использую модифицированный алгоритм обхода предварительного заказа. У меня вопрос, как я могу получить доступ ко всем узлам на уровне 2, т.е. статьи, портфолио, контакт

введите описание изображения здесь

1

Решение

Статья явно не говорит вам, как получить все узлы с одного уровня. Но если вы внимательно прочитаете его, он расскажет вам, как сделать больше -> получить счетчик глубины для каждой категории. Тогда все, что вам нужно сделать, это отфильтровать по этой глубине.

SELECT node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node, nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
HAVING depth = 1
ORDER BY node.lft;

РЕДАКТИРОВАТЬ (что происходит):

Для того, чтобы использовать lft а также rgt колонны nested_category Таблица, которую мы должны выбрать таблицу дважды.

SELECT *
FROM nested_category AS node, nested_category AS parent

если вы проверите этот запрос, вы обнаружите, что для каждой строки в nested_category мы снова выбираем все строки. Итак, что мы хотим сейчас, это удалить все строки из первой таблицы (ту, которую мы назвали AS node) где они не дети их parent, Вот почему мы фильтруем с WHERE node.lft BETWEEN parent.lft AND parent.rgt

Я хочу упомянуть, что этот запрос:

SELECT *
FROM nested_category AS node, nested_category AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
ORDER BY node.lft;

равно

SELECT *
FROM nested_category AS node
LEFT JOIN nested_category AS parent ON (node.lft BETWEEN parent.lft AND parent.rgt)
ORDER BY node.lft;

Так что теперь у нас есть все дети с их родителями + 1 (из-за того, как мы фильтруем, каждый child принадлежат себе)

+-------------+----------------------+-----+-----+-------------+----------------------+------+------+
| category_id | name                 | lft | rgt | category_id | name                 | lft  | rgt  |
+-------------+----------------------+-----+-----+-------------+----------------------+------+------+
|           1 | ELECTRONICS          |   1 |  20 |           1 | ELECTRONICS          |    1 |   20 |
|           2 | TELEVISIONS          |   2 |   9 |           1 | ELECTRONICS          |    1 |   20 |
|           2 | TELEVISIONS          |   2 |   9 |           2 | TELEVISIONS          |    2 |    9 |
|           3 | TUBE                 |   3 |   4 |           1 | ELECTRONICS          |    1 |   20 |
|           3 | TUBE                 |   3 |   4 |           3 | TUBE                 |    3 |    4 |
|           3 | TUBE                 |   3 |   4 |           2 | TELEVISIONS          |    2 |    9 |
|           4 | LCD                  |   5 |   6 |           2 | TELEVISIONS          |    2 |    9 |
|           4 | LCD                  |   5 |   6 |           1 | ELECTRONICS          |    1 |   20 |
|           4 | LCD                  |   5 |   6 |           4 | LCD                  |    5 |    6 |
|           5 | PLASMA               |   7 |   8 |           1 | ELECTRONICS          |    1 |   20 |
|           5 | PLASMA               |   7 |   8 |           5 | PLASMA               |    7 |    8 |
|           5 | PLASMA               |   7 |   8 |           2 | TELEVISIONS          |    2 |    9 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |           6 | PORTABLE ELECTRONICS |   10 |   19 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |           1 | ELECTRONICS          |    1 |   20 |
|           7 | MP3 PLAYERS          |  11 |  14 |           7 | MP3 PLAYERS          |   11 |   14 |
|           7 | MP3 PLAYERS          |  11 |  14 |           1 | ELECTRONICS          |    1 |   20 |
|           7 | MP3 PLAYERS          |  11 |  14 |           6 | PORTABLE ELECTRONICS |   10 |   19 |
|           8 | FLASH                |  12 |  13 |           1 | ELECTRONICS          |    1 |   20 |
|           8 | FLASH                |  12 |  13 |           8 | FLASH                |   12 |   13 |
|           8 | FLASH                |  12 |  13 |           6 | PORTABLE ELECTRONICS |   10 |   19 |
|           8 | FLASH                |  12 |  13 |           7 | MP3 PLAYERS          |   11 |   14 |
|           9 | CD PLAYERS           |  15 |  16 |           1 | ELECTRONICS          |    1 |   20 |
|           9 | CD PLAYERS           |  15 |  16 |           9 | CD PLAYERS           |   15 |   16 |
|           9 | CD PLAYERS           |  15 |  16 |           6 | PORTABLE ELECTRONICS |   10 |   19 |
|          10 | 2 WAY RADIOS         |  17 |  18 |           1 | ELECTRONICS          |    1 |   20 |
|          10 | 2 WAY RADIOS         |  17 |  18 |          10 | 2 WAY RADIOS         |   17 |   18 |
|          10 | 2 WAY RADIOS         |  17 |  18 |           6 | PORTABLE ELECTRONICS |   10 |   19 |
+-------------+----------------------+-----+-----+-------------+----------------------+------+------+

Следующий шаг — получить счетчик глубины. Чтобы сделать это, мы должны сгруппировать по каждому ребенку (пример использует GROUP BY node.name но это также можно сделать на node.category_id и посчитать количество parents — 1 на каждую группу (COUNT(parent.name) - 1) AS depth (его также хорошо использовать parent.category_id вместо)

Так делаю

SELECT node.*, (COUNT(parent.category_id) - 1) AS depth
FROM nested_category AS node
LEFT JOIN nested_category AS parent ON (node.lft BETWEEN parent.lft AND parent.rgt)
GROUP BY node.category_id
ORDER BY node.lft;

мы получаем это

+-------------+----------------------+-----+-----+-------+
| category_id | name                 | lft | rgt | depth |
+-------------+----------------------+-----+-----+-------+
|           1 | ELECTRONICS          |   1 |  20 |     0 |
|           2 | TELEVISIONS          |   2 |   9 |     1 |
|           3 | TUBE                 |   3 |   4 |     2 |
|           4 | LCD                  |   5 |   6 |     2 |
|           5 | PLASMA               |   7 |   8 |     2 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |     1 |
|           7 | MP3 PLAYERS          |  11 |  14 |     2 |
|           8 | FLASH                |  12 |  13 |     3 |
|           9 | CD PLAYERS           |  15 |  16 |     2 |
|          10 | 2 WAY RADIOS         |  17 |  18 |     2 |
+-------------+----------------------+-----+-----+-------+

И теперь последний шаг, чтобы сказать, что мы хотим только эти записи, которые имеют глубину = 1 (HAVING depth = 1, HAVING используется здесь, потому что применяется после агрегатов (и поэтому может фильтровать по агрегатам))

SELECT node.*, (COUNT(parent.category_id) - 1) AS depth
FROM nested_category AS node
LEFT JOIN nested_category AS parent ON (node.lft BETWEEN parent.lft AND parent.rgt)
GROUP BY node.category_id
HAVING depth = 1
ORDER BY node.lft;

+-------------+----------------------+-----+-----+-------+
| category_id | name                 | lft | rgt | depth |
+-------------+----------------------+-----+-----+-------+
|           2 | TELEVISIONS          |   2 |   9 |     1 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |     1 |
+-------------+----------------------+-----+-----+-------+

Надеюсь, теперь все понятно. Снова извините за мой плохой английский, если я сделал несколько ошибок.

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector