从 SQLite DB 树表示中选择下一个(同级)和上一个(同级)
我在 SQLite DB 中有以下示例树结构:
id | idparent | order
1 -1 0
2 1 0
3 2 0
4 1 1
它代表以下树:
1
|- 2
| |- 3
|- 4
我想创建一个 select 语句来获取下一个、上一个、下一个同级和上一个同级的所有节点。这样的语句将从上一个示例返回:
id | idparent | next | previous | nextsibling | previoussibling
1 -1 2 NULL NULL NULL
2 1 3 1 4 NULL
3 2 4 2 NULL NULL
4 1 NULL 3 NULL 2
我可以获得下一个兄弟姐妹和上一个兄弟姐妹,但我坚持下一个和上一个:
SELECT node.id, node.idparent,
??? AS next
??? AS previous,
(SELECT id FROM nodes WHERE idparent = node.idparent AND `order` > node.`order` LIMIT 1) AS nextsibbling,
(SELECT id FROM nodes WHERE idparent = node.idparent AND `order` < node.`order` LIMIT 1) AS previoussibbling
FROM nodes node;
我想我需要使用 WHERE NOT EXISTS 子句,但我不知道如何实现这一点。我应该提到的是,改变数据库结构不是一个选择。
预先感谢您的任何帮助。
I've got the following sample tree structure in an SQLite DB:
id | idparent | order
1 -1 0
2 1 0
3 2 0
4 1 1
Which represents the following tree:
1
|- 2
| |- 3
|- 4
And I would like to create a select statement to get all the nodes next, previous, next sibling and previous sibling. Such a statement would return from the previous sample:
id | idparent | next | previous | nextsibling | previoussibling
1 -1 2 NULL NULL NULL
2 1 3 1 4 NULL
3 2 4 2 NULL NULL
4 1 NULL 3 NULL 2
I can get the nextsibling and previoussiblingbut I'm stuck with the next and previous:
SELECT node.id, node.idparent,
??? AS next
??? AS previous,
(SELECT id FROM nodes WHERE idparent = node.idparent AND `order` > node.`order` LIMIT 1) AS nextsibbling,
(SELECT id FROM nodes WHERE idparent = node.idparent AND `order` < node.`order` LIMIT 1) AS previoussibbling
FROM nodes node;
I guess I need to use the WHERE NOT EXISTS clause but I can't figure out how I can achieve that. I should mention that changing the DB structure is not an option.
Thanks in advance for any help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的模式(所谓的“邻接列表模型”)在它支持的操作方面相当有限。相反,尝试嵌套集模式:存储每个节点的边界比每个节点的父节点。节点是父节点边界包含子节点边界的所有节点的后代。界限还给出了树的深度优先遍历,其中下界给出了节点进入的时间,上限给出了节点退出的时间。因此,按左边界对节点进行排序给出了前序遍历,按右边界排序给出了后序遍历。
结果:
如果您确实需要查找节点的父节点(或深度),您可以使用视图,或使用视图中应用于查询的技术:
Your schema (what's called the "adjacency list model") is rather limited in terms of which operations it supports. Instead, try the nested set mode: store bounds for each node rather than each node's parent. A node descends from all nodes where the parent's bounds contain the child's. The bounds also give the depth first traversal of the tree, where the lower bound gives when the node is entered and the upper bound gives when the node is exited. Sorting the nodes by the left bound thus gives a pre-order traversal, and sorting by the right gives a post-order traversal.
Result:
If you really need to find a node's parent (or depth), you can use a view, or use the technique applied in the view to a query:
我认为您的架构不支持
next
查询。 IIUC,您可能需要上升多个级别才能确定下一个节点。我建议添加一个
path
列,它将冒号分隔的路径作为值,例如1:2:3
或1:4
。下一个节点将是path
顺序中的下一个节点。I don't think your schema supports a
next
query. IIUC, you might need to go up multiple levels to determine the next node.I recommend to add a
path
column, which takes colon-separated paths as values, such as1:2:3
or1:4
. The next node will then be the next one inpath
order.