【问题标题】:CTE Recursive Queries in Doctrine 2.5Doctrine 2.5 中的 CTE 递归查询
【发布时间】:2017-03-27 14:04:25
【问题描述】:

我有一个表用户,它有 2 个关键列的引用者和引用代码,这是树结构的简单实现。目标是根据谁推荐他们使用此应用程序来获取用户跟踪。

NAME       |     Referrer     | Referral_Code
----------------------------------------------
Super User |     000          |  001
User A     |     001          |  002         
User B     |     002          |  003
User C     |     003          |  004
User n     |     00n          |  00n-1

我需要一个基于触发器的递归查询,例如User C 活动的报告可以产生一个关于引荐来源的跟踪字符串,最大深度为 4。 我想要的输出字符串是004-003-002-001,这意味着基于用户活动的推荐跟踪。这棵树的深度可以无限增长,因此User QA 的踪迹可以产生树上 4 个人在推荐代码上加入的堆栈跟踪。 我使用doctrine 2.5 作为ORM。 约束

  1. 必须推荐用户使用系统
  2. 一个用户可以推荐多个用户使用系统

【问题讨论】:

  • 不支持 AFAIK CTE。您需要跳过 DQL 并使用“本机查询”,或者通过数据库连接使用痛苦 SQL。无论哪种方式,您都需要在您的数据库文档中查找公用表表达式,或者如果不支持,您需要它们的等价物。

标签: sql doctrine-orm common-table-expression recursive-query


【解决方案1】:

Somnambulist.tech 构建了一个公用表表达式 (CTE) Doctrine 表达式构建器,它是用于为 WITH 子句中的子句起别名的包装器。

https://github.com/somnambulist-tech/cte-builder

简单示例:

$eb = new ExpressionBuilder($connection);
$eb->createExpression('tacos');
$eb->tacos->select('id', 'type')->from('tacos'); // or $eb->get('tacos');
$eb->execute();

【讨论】:

    【解决方案2】:

    如果 4 的深度是固定的,则不需要递归,只需进行 4 次自连接。 如果你真的想使用递归,你可以为你的 dbms 编写你自己的 DQL 函数。 http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/dql-user-defined-functions.html

    【讨论】:

    • SQL 通过 CTE 的语法支持递归。自定义功能是不够的。如果有办法添加自定义语法...