我有一个小问题我有一个名为类别的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的ID我可以添加{{1}只有第一个AND status = 0
,然后才会选择状态为0的父类别,因此当UNION生成时,它的子项也不会被选中。但是,如果我只是将SELECT WHERE
添加到第一个AND status = 1
,那么我只会获得带有WHERE
的类别,并且UNION中没有任何内容。
2。问题
一旦我这样选择,我将不得不按照位置值来排序类别和子类别,这可以使用排序函数在PHP中完成,但是当你有大约8000个类别时,这是非常广泛的。
我尝试添加parent_id & status = 1
。在我上次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 |
我认为第二个例子非常简单,当我的声明不包含UNION ALL时我就开始工作了。但是使用UNION我的语句就像status = 1一样只返回父类别。
| id | parent_id | position |
| 1 | 0 | 1 |
| 2 | 0 | 2 |
| 3 | 1 | 1 |
| 6 | 1 | 2 |
| 4 | 2 | 1 |
由于所有父母都有parent_id = 0,所以他们会先被列出,但是按位置排序,然后所有子女将先由parent_id和位置一起订购。
答案 0 :(得分:1)
如果我理解正确,我想你想要以下内容:
SELECT DISTINCT c.* FROM categories c, categories p
WHERE c.status<>0 and (c.parent_id = 0 OR (c.parent_id=p.id and p.parent_id=0))
ORDER BY c.id,c.position