问题描述
我有以下数据:
MysqL> SELECT id,parent_id,name FROM account_type WHERE account_classification_id = 1 LIMIT 7;
+----+-----------+----------------------+
| id | parent_id | name |
+----+-----------+----------------------+
| 30 | NULL | AKTIVA |
| 40 | 30 | Aktiva Lancar |
| 41 | 40 | Kas & Bank |
| 42 | 41 | Kas |
| 43 | 41 | Kas Tunai USD |
| 44 | 41 | Kas Tunai Di Brankas |
| 46 | 41 | Bank |
+----+-----------+----------------------+
7 rows in set (0.00 sec)
因此,使用 CTE:
WITH RECURSIVE account_path (root,id,name,lvl,`sort`,account_roll_up_id) AS
(
SELECT
id AS root,`name`,0 lvl,account_roll_up_id
FROM account_type
WHERE id IN (30,213)
UNION ALL
SELECT
ap.root,at.id,at.parent_id,at.name,(ap.lvl + 1),at.sort,at.account_roll_up_id
FROM account_path AS ap
JOIN account_type AS at ON ap.id = at.parent_id
)
SELECT * FROM `account_path`
ORDER BY account_path.sort
;
+------+------+-----------+----------------------+------+------+--------------------+
| root | id | parent_id | name | lvl | sort | account_roll_up_id |
+------+------+-----------+----------------------+------+------+--------------------+
| 30 | 30 | NULL | AKTIVA | 0 | 1 | NULL |
| 30 | 40 | 30 | Aktiva Lancar | 1 | 2 | 2 |
| 30 | 41 | 40 | Kas & Bank | 2 | 3 | 2 |
| 30 | 42 | 41 | Kas | 3 | 4 | 2 |
| 30 | 43 | 41 | Kas Tunai USD | 3 | 5 | 2 |
| 30 | 44 | 41 | Kas Tunai Di Brankas | 3 | 6 | 2 |
| 30 | 46 | 41 | Bank | 3 | 7 | 2 |
+------+------+-----------+----------------------+------+------+--------------------+
7 rows in set (0.01 sec)
当我检索所有节点时,我需要每一行都有一个布尔值来确定 is_a_leaf_node, 是否有可能? 像这样:
+------------+------+------+-----------+----------------------+------+------+--------------------+
| is_a_leaf | root | id | parent_id | name | lvl | sort| account_roll_up_id |
+------------+------+------+------------+----------------------+------+-----+--------------------+
| FALSE| 30 | 30 | NULL | AKTIVA | 0 | 1 | NULL |
| FALSE| 30 | 40 | 30 | Aktiva Lancar | 1 | 2 | 2 |
| FALSE| 30 | 41 | 40 | Kas & Bank | 2 | 3 | 2 |
| TRUE | 30 | 42 | 41 | Kas | 3 | 4 | 2 |
| TRUE | 30 | 43 | 41 | Kas Tunai USD | 3 | 5 | 2 |
| TRUE | 30 | 44 | 41 | Kas Tunai Di Brankas | 3 | 6 | 2 |
| TRUE | 30 | 46 | 41 | Bank | 3 | 7 | 2 |
+------------+------+------+-----------+----------------------+------+------+--------------------+
解决方法
已解决,谢谢@Akina
WITH RECURSIVE account_path (is_a_leaf,root,id,parent_id,name,lvl,`sort`,account_roll_up_id) AS
(
SELECT id is_a_leaf,id AS root,`name`,0 lvl,account_roll_up_id
FROM account_type
WHERE id IN (30,213)
UNION ALL
SELECT (SELECT EXISTS(
SELECT parent_id
FROM account_type
WHERE parent_id = at.id
)),ap.root,at.id,at.parent_id,at.name,(ap.lvl + 1),at.sort,at.account_roll_up_id
FROM account_path AS ap
JOIN account_type AS at ON ap.id = at.parent_id
)
SELECT *
FROM `account_path`
ORDER BY account_path.sort
LIMIT 7;