MySQL - 如何访问 table 级别 2 中的所有节点

MySQL - How to access all nodes in level 2 in table

我正在为具有嵌套类别的 e-commerce 网站创建数据库,并且我正在使用 修改后的预序遍历算法 。我的问题是如何访问级别 2 中的所有节点,即 ArticlesPortfolioContact

The article 没有明确告诉您如何从一个级别获取所有节点。但如果你仔细阅读它,它会告诉你如何做更多 -> 获取每个类别的深度计数。然后你所要做的就是按那个深度过滤。

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;

编辑(发生了什么):

为了利用 nested_category table 的 lftrgt 列,我们应该 select 两次 table .

SELECT *
FROM nested_category AS node, nested_category AS parent

如果您检查此查询,您会发现对于 nested_category 中的每一行,我们再次 select 所有行。所以我们现在想要的是从第一个 table(我们称为 AS node 的行)中删除它们不是 parent 的 child 的所有行。这就是我们使用 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;

所以现在我们拥有所有 child 及其 parents + 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 |
+-------------+----------------------+-----+-----+-------------+----------------------+------+------+

下一步 - 获取深度计数。为了做到这一点,我们必须按每个 child 进行分组(该示例使用 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 |
+-------------+----------------------+-----+-----+-------+

我希望现在更清楚了。如果我犯了一些错误,再次为我糟糕的英语感到抱歉。