我有一张桌子:
element_id, element_parent_id
记录是:
1, null
2, 1
3, 1
4, null
因此,可视化可能如下所示:
1
2
3
4
问题是,如何选择:
form_id
3
4
...换句话说:如果没有孩子,如何选择父母,如果存在孩子,则选择最新的孩子。到目前为止,我设法选择:
1 and 4
2 and 3
1, 2, 3 and 4
答案 0 :(得分:2)
为了更有用,我将解释我的推理到达最终查询(在底部)。
您正在从相同的表中选择两个不同的实体,因此您需要自己的JOIN
表;这会给你父母和孩子。
但是孩子可能不在那里,所以它必须是LEFT JOIN
。
SELECT p.id, c.id AS cid
FROM yourtable AS p
LEFT JOIN yourtable AS c ON (c.parent_id = p.id);
+------+------+
| id | cid |
+------+------+
| 1 | 3 | # This one...
| 1 | 2 | # ...and this one must be grouped, and 3 taken.
| 3 | NULL | <-- this must be ignored because it's a child
| 4 | NULL |
| 2 | NULL | <-- this must be ignored because it's a child
+------+------+
现在要进一步完善,我们发现我们需要忽视父母&#34;中的孩子。角色和为此目的我们添加WHERE p.parent_id IS NULL
。 &#34;真&#34;孩子有父母,然后会被跳过。
注意:如果我们有多层次的层次结构,那么我们需要做一些更复杂的事情。如果我们只想要 底层,即&#34; true&#34;孩子(忽略那些有父母的孩子 我们自己就是父母),例如我们可以运行第二个
LEFT JOIN
获得* grand *父母,并强加祖父母的身份不是 空值。这仅适用于三级和更大的孙子。要么 我们可以让孩子的孩子并强加他们的孩子 NULL id,即它们不存在;这仅适用于 bottom 或 最后一级的孩子。其他要求可能需要另一套 边界。
然后你想要&#34; top&#34;与父ID相关的子项,这需要GROUP BY
,当孩子在那里时会产生所需的结果,或者在没有孩子时产生NULL。
SELECT p.id, MAX(c.id) AS cid
FROM yourtable AS p
LEFT JOIN yourtable AS c ON (c.parent_id = p.id)
WHERE p.parent_id IS NULL
GROUP BY p.id;
+------+------+
| id | cid |
+------+------+
| 1 | 3 |
| 4 | NULL |
+------+------+
在那的情况下,我们看到信息位于父 -side列(id
)。
要选择哪个,我会使用SUBSELECT
。
SELECT CASE WHEN cid IS NULL THEN id ELSE cid END AS wanted
FROM (
SELECT p.id, MAX(c.id) AS cid
FROM yourtable AS p
LEFT JOIN yourtable AS c ON (c.parent_id = p.id)
WHERE p.parent_id IS NULL
GROUP BY p.id
) AS x;