【问题标题】:How exactly does SQL recursion work?SQL 递归究竟是如何工作的?
【发布时间】:2013-07-06 17:11:59
【问题描述】:

我需要在不同的表上编写一系列查询。它们都是同一类型,一条记录有一个父记录,也可以有父记录。

我最终需要:

  1. 在层次结构中查找最高记录
  2. 找到层次结构中的最低点
  3. 找到所有的祖先
  4. 查找所有后代

我使用的是 Filemaker Pro,我不相信递归 SQL 查询可以在本地运行。有一些方法可以使用本机(递归)函数来实现所有 4 件事,这些函数可以填充实体(表)上的属性(字段),然后我可以查询这些属性(字段)。但是,我想了解 SQL 递归的工作原理,看看我是否能找到更有效的方法来执行这些任务。

感谢您的帮助!

【问题讨论】:

  • 我知道您可以使用 SQL 从 FileMaker 查询其他数据库,但我不知道您可以使用 SQL 查询 FileMaker 数据库。
  • @zneak 从 Filemaker 12 开始,ExecuteSQL 函数增加了这样做的能力。

标签: sql recursion hierarchy filemaker recursive-query


【解决方案1】:

SQL 递归并不常见,许多 SQL 方言根本不支持它。 FileMaker 就是其中之一。它的 SQL 相当基本(例如,它没有 LIMIT)并且通常效率低于本地 FileMaker 方法(例如,如果您使用独立的子查询,它似乎仍然可以重新运行 主查询中的每一行)。也就是说,如果您使用 FileMaker 并且对递归 SQL 感兴趣,那一定是一个纯粹的学术练习。如果您对此感兴趣,那么this Wikipedia article on hierarchical and recursive SQL 可能是一个好的开始。

但是你不需要 SQL 来做你想做的事;您可以通过相当简单的 FileMaker 计算来完成所有这些工作。假设您的分层表使用IDParent ID 以及两个关系ParentChild,则创建以下字段:

Root ID =
If( IsEmpty( Parent::ID ); ID; /* else */ Parent::Root ID )

Leaf IDs = 
If( IsEmpty( Child::ID ); ID; /* else */ List( Child::Leaf IDs ) )

Ancestor IDs =
List( Case( not IsEmpty( Parent::ID ); Parent::Ancestor IDs ); ID )

Descendant IDs =
List( ID; Case( not IsEmpty( Child::ID ); List( Child::Descendant IDs ) ) )

如您所见,每个字段都有一个引用自身的递归公式。添加字段后,您将无法立即输入它,因为此时该字段尚未保存,FileMaker 会抱怨找不到它。要解决此问题,请先创建一个字段,将其保存,然后再次对其进行编辑并输入公式。

【讨论】:

  • 我使用的数据模型大量使用了这个子/父概念来扩展定制的灵活性(即产品组件化)。我试图找出您列出的函数的其他替代方案有两个原因:1)因为它在数据模型中被大量使用,我希望我不必弄乱关系图和 2 ) 我将不得不将这些查询的结果(递归计算字段)用作另一个查询中的“where”子句,并且我希望更好地理解整个概念,看看哪个是最有效和最灵活的方法。
  • 我正在处理的总体问题是this one,如果您有任何想法,我将不胜感激。
  • LIMIT 不是标准的。这是一个 MySQL 扩展。
猜你喜欢
  • 2013-03-09
  • 2021-01-27
  • 2021-07-05
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 2011-06-26
  • 2021-08-15
  • 2012-06-08
相关资源
最近更新 更多