在SQL中实现排序键

use*_*779 1 sql oracle

我们使用具有名为docid的列和名为parentid的列的表来存储Oracle数据库中的文档之间的关系.如果我有一个与子文档相关的文档doc1,child1_1和child1_2,它们将由Documents表中的以下记录表示.

docid  parentid
1000   null    record for doc1
1001   1000    "       "  child1_1
1002   1000    "       "  child1_2
Run Code Online (Sandbox Code Playgroud)

Documents表可以包含数百万行,因此为了确保所有相关文档在我们的UI中组合在一起,我们使用名为sortedfamily的索引varchar列对Documents表进行预排序,并使用相关文档的docids的连接对其进行填充. .如果不使用sortedfamily列,则在查询时对记录进行排序太慢.上面显示的记录成为.

docid  parentid  sortedfamily
1000   null      1000           record for doc1
1001   1000      1000_1001      "       "  child1_1
1002   1000      1000_1002      "       "  child1_2
Run Code Online (Sandbox Code Playgroud)

这允许我们将"ordered by sortedfamily"添加到我们的查询中,并且返回的记录将始终按相关文档排序.我上面概述的工作非常好,但它有一些与文档族层次深度相关的限制,并且感觉奇怪的连接整数来对记录进行排序.有没有办法只使用整数执行上述操作?

提前致谢.

更新:我上面的例子不够详细.孩子们自己也可能有相关文件.如果child1_1具有相关文档,则sortedfamily的结果值可能是"1000_1001_2000".

Ed *_*bbs 5

Oracle对分层查询提供了出色的支持.您可以在不依赖sortedfamily列的情况下获取文档层次结构.这是查询:

SELECT docid, PRIOR docid AS "Parent"
FROM Documents
START WITH parentid IS NULL
CONNECT BY parentid = PRIOR docid
ORDER SIBLINGS BY docid
Run Code Online (Sandbox Code Playgroud)

现在解释一下:

SELECT docid, PRIOR docid AS "Parent"
Run Code Online (Sandbox Code Playgroud)

这通过"回顾" PRIOR操作符使文档及其父级在同一行上.

START WITH parentid IS NULL
Run Code Online (Sandbox Code Playgroud)

这定义了层次结构的根.每个具有null的行都parentid被视为分支的根.

CONNECT BY parentid = PRIOR docid
Run Code Online (Sandbox Code Playgroud)

这表示当前行的"父级"由parentid子级连接到docid父级.

ORDER SIBLINGS BY docid
Run Code Online (Sandbox Code Playgroud)

这将按整个层次结构排序,而不是单个值.这很难解释,但它确实有效.

关于Oracle分层查询的最好的事情是它们将查询整个分支,所以如果你有一个孩子的文档有一个孩子(有一个孩子,并且......),Oracle会处理它.它还将处理每个父母的多个孩子.

这里有一个SQL小提琴,包含您的数据和一些其他文档.

小提琴还包括一个列,该列使用该SYS_CONNECT_BY_PATH函数显示整个"根到分支"的关系.在SYS_CONNECT_BY_PATH做同样的事情为你sortedfamily列,但它确实是动态的,无需维护的列.这也是可视化层次结构的每个分支的好方法.

附录

请注意,上面的查询将返回每个文档的每个分支.如果您只对单个文档感兴趣,请将其替换为:docid = 1000START WITH parentid IS NULL

START WITH docid = 1000
Run Code Online (Sandbox Code Playgroud)

那将为你提供docid1000 的整个分支.如果你有一个索引docid就会非常快.