我有一个MySQL查询,我认为它可以很好地检索每个节点的所有祖先,从顶部节点开始,一直到其直接节点。但是当我将第五级添加到嵌套集合中时,它就出现了故障。
以下是示例表、查询和SQL Fiddles:
四级嵌套集合:
CREATE TABLE Tree
(title varchar(20) PRIMARY KEY,
`tree` int,
`left` int,
`right` int);
INSERT Tree
VALUES
("Food", 1, 1, 18),
('Fruit', 1, 2, 11),
('Red', 1, 3, 6),
('Cherry', 1, 4, 5),
('Yellow', 1, 7, 10),
('Banana', 1, 8, 9),
('Meat', 1, 12, 17),
('Beef', 1, 13, 14),
('Pork', 1, 15, 16);
查询:
SELECT t0.title node
,(SELECT GROUP_CONCAT(t2.title)
FROM Tree t2
WHERE t2.left<t0.left AND t2.right>t0.right
ORDER BY t2.left) ancestors
FROM Tree t0
GROUP BY t0.title;
节点
Banana
的返回结果为食物、水果、黄色
- 完美。您可以在此处查看:SQL Fiddle - 4 Levels
当我在下面的5级表上运行相同的查询时,第5级节点的顺序错误:CREATE TABLE Tree
(title varchar(20) PRIMARY KEY,
`tree` int,
`left` int,
`right` int);
INSERT Tree
VALUES
("Food", 1, 1, 24),
('Fruit', 1, 2, 13),
('Red', 1, 3, 8),
('Cherry', 1, 4, 7),
('Cherry_pie', 1, 5, 6),
('Yellow', 1, 9, 12),
('Banana', 1, 10, 11),
('Meat', 1, 14, 23),
('Beef', 1, 15, 16),
('Pork', 1, 17, 22),
('Bacon', 1, 18, 21),
('Bacon_Sandwich', 1, 19, 20);
Bacon_Sandwich
的返回结果是 Bacon,Food,Meat,Pork
,顺序不正确,应该是 Food,Meat,Pork,Bacon
- 在此处可以看到 SQL Fiddle - 5 Levels
我不确定发生了什么,因为我不太理解子查询。是否有人能提供一些解释呢?经过调查后更新:
哇!!看起来写下所有这些内容并阅读关于使用
GROUP_CONCAT
排序的文章给了我一些启示。将
ORDER BY
添加到实际的 GROUP_CONCAT
函数中,并从子查询末尾删除解决了问题。我现在收到的是节点 Bacon_Sandwich
的Food,Meat,Pork,Bacon
。SELECT t0.title node
,(SELECT GROUP_CONCAT(t2.title ORDER BY t2.left)
FROM Tree t2
WHERE t2.left<t0.left AND t2.right>t0.right
) ancestors
FROM Tree t0
GROUP BY t0.title;
我仍然不知道为什么。在子查询的末尾使用ORDER BY
可以解决4级问题,但不能解决5级问题?!?
如果有人能解释问题以及为什么移动ORDER BY
可以解决它,我将非常感激。
GROUP_CONCAT()
的工作原理,我只是假设它在整个查询运行后才执行其操作,这将按照末尾的ORDER BY
对结果进行排序。老实说,我仍然不太确定为什么会这样。毫无疑问,GROUP_CONCAT()
知道要连接的内容是通过SELECT
查询得到的。而SELECT
查询中有ORDER BY
,所以它应该按顺序返回要“连接”的内容!?!?显然我漏掉了什么.....?只是为了明确,我知道GROUP_CONCAT()
将结果连接成一行......那不是我的困惑点...... - superphonicGROUP BY
。GROUP_CONCAT()
不是在所选字段上操作,而是在分组字段上操作。你的查询(没有GROUP BY
)只是一个GROUP BY
查询的快捷方式。 - Markus Malkusch