我有表 tbl_budget 列 id、budget_code 和 level。级别告诉层次结构 当前表视图
我想根据每个预算代码的级别找到它的父级
这个查询确实找到了一级父母很好,但在那之后就不行了
SELECT tb1.id ,(从 tbl_budget 选择 buget_code where level = tb1.level-1 LIMIT 0,1)作为 tbl_budget tb1 的父级
我有表 tbl_budget 列 id、budget_code 和 level。级别告诉层次结构 当前表视图
我想根据每个预算代码的级别找到它的父级
这个查询确实找到了一级父母很好,但在那之后就不行了
SELECT tb1.id ,(从 tbl_budget 选择 buget_code where level = tb1.level-1 LIMIT 0,1)作为 tbl_budget tb1 的父级
如果我正确理解了您的层次结构,那么您可以使用LIKE
比较 ON 子句中的 budget_codes:
select c.*, p.id as parent_id, p.budget_code as parent_budget_code
from tbl_budget c
left join tbl_budget p
on p.level = c.level - 1
and c.budget_code like concat(p.budget_code, '%')
order by c.id
结果:
| id | budget_code | level | parent_id | parent_budget_code |
| --- | ----------- | ----- | --------- | ------------------ |
| 1 | 001 | 1 | | |
| 2 | 001-1 | 2 | 1 | 001 |
| 3 | 001-2 | 2 | 1 | 001 |
| 4 | 001-2-1 | 3 | 3 | 001-2 |
| 5 | 002 | 1 | | |
| 6 | 002-1 | 2 | 5 | 002 |
| 7 | 002-2 | 2 | 5 | 002 |
另一种方法是使用SUBSTRING_INDEX()
:
select c.*, p.id as parent_id, p.budget_code as parent_budget_code
from tbl_budget c
left join tbl_budget p
on p.budget_code = substring_index(c.budget_code, '-', c.level - 1)
order by c.id
如果你只需要budget_code
父的,那么你甚至不需要加入,因为父代码是子代码的一部分,你只需要提取它:
select c.*,
substring_index(c.budget_code, '-', c.level - 1) as parent
from tbl_budget c
检查以下查询:
架构(MySQL v5.7)
create table tbl_budget (
`id` INT ,
`budget_code` VARCHAR(255),
`level` INT
);
INSERT INTO `tbl_budget` VALUES
(1, '001', 1),
(2, '001-1', 2),
(3, '001-2', 2),
(4, '001-2-1', 3),
(5, '002', 1),
(6, '002-1', 2),
(7, '002-2', 2);
询问
SELECT
@count_dash := LENGTH(tb1.budget_code) - LENGTH(REPLACE(tb1.budget_code, '-', '')) as count_dash,
tb1.id,
tb1.budget_code,
SUBSTRING_INDEX(tb1.budget_code, '-', -1) as child_part,
SUBSTRING_INDEX(tb1.budget_code, '-', @count_dash) as parent_part,
(
SELECT id
FROM tbl_budget
WHERE
`level` = tb1.level-1 AND parent_part = `budget_code`
LIMIT 1
) as parent_id
FROM tbl_budget tb1;
| count_dash | child_part | parent_part | parent_id | id | budget_code |
| ---------- | ---------- | ----------- | --------- | --- | ----------- |
| 0 | 001 | | | 1 | 001 |
| 1 | 1 | 001 | 1 | 2 | 001-1 |
| 1 | 2 | 001 | 1 | 3 | 001-2 |
| 2 | 1 | 001-2 | 3 | 4 | 001-2-1 |
| 0 | 002 | | | 5 | 002 |
| 1 | 1 | 002 | 5 | 6 | 002-1 |
| 1 | 2 | 002 | 5 | 7 | 002-2 |
我假设您的数据中存在命名一致性。问题是要获取条目的父项,您不仅需要level
匹配的代码,还需要匹配的部分代码
步骤1:
以下计算 '-' 中的数量budget_code
:
@count_dash := LENGTH(tb1.budget_code) - LENGTH(REPLACE(tb1.budget_code, '-', ''))
第2步:
budget_code
现在,我们用'-'分割并返回:
-1
) 是子代码这是使用 SUBSTRING_INDEX 完成的,它按该字符拆分给定的字符串并返回请求的部分数量
第 3 步:
由于每个代码都有一个父级,我们加入并返回父级的 id。要找到正确的,我们需要满足以下条件:
上面向您展示了如何获取父代码(即使没有加入)。但是,您的查询可以简化为以下内容:
SELECT
tb1.id,
tb1.budget_code,
(
SELECT id
FROM tbl_budget
WHERE
`level` = tb1.level-1
AND tb1.budget_code LIKE CONCAT(budget_code, '%')
LIMIT 1
) as parent_id
FROM tbl_budget tb1;
在这种情况下,我们说:找到一个条目,比当前条目高一级,并且其budget_code 包含在当前条目中。请注意,您可以将 parent_id 更改为 parent_code,但是如果需要代码,我会避免加入