【发布时间】:2014-02-22 03:24:16
【问题描述】:
我有一个小问题,我有一个名为 categories 的 MySQL 表,看起来像这样:
| id | parent_id | name | position | status | ... |
| 1 | 0 | A | 1 | 1 | ... |
| 2 | 1 | A1 | 2 | 1 | ... |
| 3 | 2 | A2 | 1 | 1 | ... |
| 4 | 1 | A3 | 1 | 1 | ... |
| 5 | 0 | B | 2 | 1 | ... |
基本上是一个包含我所有具有多层次深度的类别的表,作为子类别的每个类别都有一个parent_id > 0。在任何给定时间,我都使用以下 SQL 语句仅选择具有 parent_id = 0 的顶级类别及其具有 parent_id = id 的类别的 parent_id = 0 的第一级子类别。
SELECT * FROM categories WHERE parent_id = 0 UNION ALL SELECT c.* FROM categories c
INNER JOIN categories p ON c.parent_id = p.id WHERE p.parent_id
1.问题
这将始终选择所有类别,即使它们有 status = 0 这是一个问题。因此,我尝试将AND status = 1 添加到两个WHERE 语句中,但是这不起作用,因为无论状态如何,所有类别都被选中。
我尝试的第二件事是,因为在第一次选择时,我只选择带有parent_id = 0 的类别,然后使用所有类别创建一个 UNION,其中 parent_id 与第一次选择的那些 id 匹配我可以只添加 AND status = 0 到首先是SELECT WHERE,然后是状态为 0 的父类别不会被选中,因此当 UNION 被创建时,它的子类也不会被选中。但是,如果我只是将AND status = 1 添加到第一个WHERE,那么我只会获得parent_id & status = 1 的类别,并且在UNION 中什么也没有发生。
2。问题
一旦我进行了这个选择,我将不得不按位置值对类别和子类别进行排序,这可以在 PHP 中使用 sort 函数来完成,但是当你有大约 8000 个类别时,这是相当广泛的。
我尝试添加ORDER BY id ASC, position ASC。在我的最后一个 WHERE 声明之后,我想要它,这样我就可以得到这样的输出:
| id | parent_id | position |
| 1 | 0 | 1 |
| 3 | 1 | 1 |
| 6 | 1 | 2 |
| 2 | 0 | 2 |
| 4 | 2 | 1 |
甚至:
| id | parent_id | position |
| 1 | 0 | 1 |
| 2 | 0 | 2 |
| 3 | 1 | 1 |
| 6 | 1 | 2 |
| 4 | 2 | 1 |
我认为第二个例子很简单,当我的语句不包括 UNION ALL 时,我让它工作。但是使用 UNION 我的语句就像 status = 1 一样只返回父类别。
SELECT * FROM categories WHERE parent_id = 0 UNION ALL SELECT c.* FROM categories c
INNER JOIN categories p ON c.parent_id = p.id WHERE p.parent_id ORDER BY parent_id ASC, position ASC;
由于所有父母的 parent_id = 0,它们将首先列出,但按位置排序,然后所有子级将首先按 parent_id 排序,然后按位置排序。
【问题讨论】:
-
你能创建an sqlfiddle吗?