SQL整齐地自我加入一个表n次

时间:2017-11-14 11:20:13

标签: sql

我正在构建一个项目的后端来构建一个(纯函数式)图形数据库系统。

我试图实现的一个操作是将预先计算的视图自身加入到自身n次(即在图中找到与特定关系完全相同的n个实例的结果对)

我提出的一个稍微丑陋的解决方案是以类似于exponentiation by squaring

的样式生成一个大型连接树

有更简洁/更好的方法吗?也许使用递归查询?

每个可能的预生成视图都有一个left_id和right_id字段,它们表示实体表中的索引。

简化示例如下:

鉴于以下表格表示关系n -> succ(n)的一部分(实际上关系可能要复杂得多)

left_id | right_id
__________________
   1    |    2
   2    |    3
   3    |    4
   4    |    5
   5    |    6
   7    |    8

使用n = 3查询的理想结果是

left_id | right_id
__________________
   1    |    4
   2    |    5
   3    |    6
   4    |    7
   5    |    8

(解释为什么我使用SQL是这个项目的一部分是为了证明SQL对于这样一个系统来说是一个糟糕的选择,然后是一个更加定制的后端来解决使用底层的问题关系而不是图模型)

1 个答案:

答案 0 :(得分:0)

许多数据库支持递归CTE,它直接支持这种图形行走。

即使在没有的数据库中,使用动态SQL和WHERE子句也不是特别困难:

对于n = 1:

select t1.left_id, t2.right_id
from t t1 join
     t t2
     on t2.left_id = t1.right_id;

对于n = 2:

select t1.left_id, t3.right_id
from t t1 join
     t t2
     on t2.left_id = t1.right_id join
     t t3
     on t3.left_id = t2.right_id;

对于n = 3:

select t1.left_id, t4.right_id
from t t1 join
     t t2
     on t2.left_id = t1.right_id join
     t t3
     on t3.left_id = t2.right_id join
     t t4
     on t4.left_id = t3.right_id;

“n”的每个附加值都会增加另一个join条件。这些查询可以很容易地利用表上的索引,因此性能应该合理。

这是否比图表数据库更好或更差有点没有实际意义。每种类型的数据库都有不同的优势。许多关系数据库确实支持递归CTE(因此图形行走)。但是,在专门为此目的而设计的软件系统上,性能可能会更好。