通过UNION ALL中的两个字段进行选择并在行之间进行排序

时间:2014-02-21 19:12:55

标签: mysql sql

我有一个小问题我有一个名为类别的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和位置一起订购。

1 个答案:

答案 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