我正在使用MySQL,是否有可能从表结构的单个SQL语句中获得以下结果?
目前,我可以通过在PHP代码中使用逻辑while循环来获得相同的结果。如果我能在单个SQL中实现性能,那将是很好的。
预期结果:
|----------+-----------------------------------------------+
| Id (PK) + headerANDsubheader +
|----------+-----------------------------------------------+
| 1 + A-head +
| 4 + -A-head-A1-subHead +
| 5 + -A-head-A2-subHead +
| 6 + --A-head-A1-subHead-A1.1-subHead +
| 7 + --A-head-A1-subHead-A1.2-subHead +
列Id
是主键。如果父键为0则表示其根级别标题。
如果ParentKey
不等于0,则表示它是某人的子标题,ParentKey
是指针。{/ p>
表: Header_sub
|----------+-----------------------------------------------+------------+
| Id (PK) + headerANDsubheader + ParentKey +
|----------+-----------------------------------------------+------------+
| 1 + A-head + 0 +
|----------+-----------------------------------------------+------------+
| 2 + B-head + 0 +
|----------+-----------------------------------------------+------------+
| 3 + C-head + 0 +
|----------+-----------------------------------------------+------------+
| 4 + A-head-A1-subHead + 1 +
|----------+-----------------------------------------------+------------+
| 5 + A-head-A2-subHead + 1 +
|----------+-----------------------------------------------+------------+
| 6 + A-head-A1-subHead-A1.1-subHead + 4 +
|----------+-----------------------------------------------+------------+
| 7 + A-head-A1-subHead-A1.2-subHead + 4 +
|----------+-----------------------------------------------+------------+
我正在尝试这样......
SELECT
CONCAT(REPEAT(' ', (COUNT(parent.subject_group_name) - 1) ), node.subject_group_name) AS name
FROM
major_scholastic as node,
major_scholastic as parent
WHERE
node.s_gid BETWEEN parent.s_gid AND parent.parent_id
GROUP BY node.subject_group_name
ORDER BY node.s_gid
答案 0 :(得分:0)
您的headerANDsubheader
列是某种物化路径。这允许您使用JOIN
条件LIKE
来获取所有祖先(不仅是直接父级)。
以下查询演示了如何获取不同任务可能需要的信息:
select node.*
, group_concat(anc.Id order by char_length(anc.headerANDsubheader)) as idPath
, group_concat(lpad(anc.Id, 10, 0) order by char_length(anc.headerANDsubheader)) as idPathSortable
, count(anc.Id) as depthLevel
, concat(repeat('- ', count(anc.Id)-1), node.headerANDsubheader) as indendtedHeader
from header_sub node
join header_sub anc
on node.headerANDsubheader like concat(anc.headerANDsubheader, '%')
group by node.Id
order by idPathSortable
结果如下:
| Id | headerANDsubheader | ParentKey | idPath | idPathSortable | depthLevel | indendtedHeader |
|----|--------------------------------|-----------|--------|----------------------------------|------------|------------------------------------|
| 1 | A-head | 0 | 1 | 0000000001 | 1 | A-head |
| 4 | A-head-A1-subHead | 1 | 1,4 | 0000000001,0000000004 | 2 | - A-head-A1-subHead |
| 6 | A-head-A1-subHead-A1.1-subHead | 4 | 1,4,6 | 0000000001,0000000004,0000000006 | 3 | - - A-head-A1-subHead-A1.1-subHead |
| 7 | A-head-A1-subHead-A1.2-subHead | 4 | 1,4,7 | 0000000001,0000000004,0000000007 | 3 | - - A-head-A1-subHead-A1.2-subHead |
| 5 | A-head-A2-subHead | 1 | 1,5 | 0000000001,0000000005 | 2 | - A-head-A2-subHead |
| 2 | B-head | 0 | 2 | 0000000002 | 1 | B-head |
| 3 | C-head | 0 | 3 | 0000000003 | 1 | C-head |
现在知道这是获得所需结果的一小步:
select node.Id, concat(
repeat(' ', count(anc.Id)-1),
repeat('-', count(anc.Id)-1),
node.headerANDsubheader
) as indendtedHeader
from header_sub node
join header_sub anc
on node.headerANDsubheader like concat(anc.headerANDsubheader, '%')
group by node.Id
order by group_concat(lpad(anc.Id, 10, 0) order by char_length(anc.headerANDsubheader))
结果:
| Id | indendtedHeader |
|----|------------------------------------|
| 1 | A-head |
| 4 | -A-head-A1-subHead |
| 6 | --A-head-A1-subHead-A1.1-subHead |
| 7 | --A-head-A1-subHead-A1.2-subHead |
| 5 | -A-head-A2-subHead |
| 2 | B-head |
| 3 | C-head |
<强>更新强>
join header_sub anc
on node.headerANDsubheader like concat(anc.headerANDsubheader, '%')
anc
是&#34; ancestor&#34;的快捷方式。我们希望将每个节点与其所有祖先(包括其自身)连接起来。条件可以读为anc.headerANDsubheader IS PREFIX OF node.headerANDsubheader
。所以&#34; A-head-A1-subHead-A1.1-subHead&#34;将加入&#34; A-head&#34;,&#34; A-head-A1-subHead&#34;和&#34; A-head-A1-subHead-A1.1-subHead&#34;。按node.id
对结果进行分组,我们可以使用聚合COUNT
获取深度级别,GROUP_CONCAT
生成有用的路径。但是,最好将深度和路径存储在表格中,因此我们根本不需要连接。