不是 ANSI 标准 SQL,不是,不是。好吧,这并不完全正确。您可以进行左外连接并添加足够的内容以覆盖可能的最大深度,但除非您限制最大深度并包含那么多连接,否则它并不总是有效。
如果您的行集足够小(比如少于 1000 行),只需将它们全部检索出来,然后再计算出来。它很可能比单次读取遍历更快。
您可以批处理父遍历。有这样的查询:
SELECT t1.id id1, t1.parent parent1,
t2.id id2, t2.parent parent2,
t3.id id3, t3.parent parent3,
t4.id id4, t4.parent parent4,
t5.id id5, t5.parent parent5
FROM mytable t1
LEFT OUTER JOIN mytable t2 ON t1.parent = t2.id
LEFT OUTER JOIN mytable t3 ON t2.parent = t3.id
LEFT OUTER JOIN mytable t4 ON t3.parent = t4.id
LEFT OUTER JOIN mytable t5 ON t4.parent = t5.id
WHERE t1.id = 1234
并将其扩展到您想要的任何数字。如果最后检索到的父级不为空,那么您还没有位于树的顶部,因此再次运行查询。这样,您应该有望将其减少到 1-2 次往返。
除此之外,您还可以查看在 ID 中编码该数据的方法。不建议这样做,但是如果您将每个节点限制为 100 个子节点,您可以说 ID 为 10030711 的节点的路径为 10 -> 03 -> 07 -> 11。这当然还有其他问题(例如 max ID 长度),当然它是 hacky。
另外值得注意的是,SQL 中有两种用于分层数据的基本模型。邻接表和嵌套集。你的方式(这很常见)是一个邻接集。嵌套集在这种情况下并没有真正的帮助,而且在它们上进行插入很复杂。