【问题标题】:Doctrine Conditional joins学说条件连接
【发布时间】:2014-10-23 14:10:57
【问题描述】:

我正在试图弄清楚如何在学说中实现条件连接。

我有一个实体A 有两个字段,我们分别称它们为b(引用单个Bobject)和c(引用单个C 对象)。

/**
* @Entity
**/
class A
{
    /** @ManyToOne(targetEntity="B") **/
    protected $b;
    /** @OneToOne(targetEntity="C") **/
    protected $c;
}

我想编写一个 DQL 查询,该查询仅在 $b 不为空时对 $b 执行 INNER JOIN,如果 $b 为空,则应将 INNER JOIN 应用于$c而是(如果 $c 也不为空)。

我尝试将INNER JOINSWITH 子句结合起来检查空值,但这显然不起作用。

SELECT a FROM model\entity\A a
INNER JOIN a.b ab WITH ab IS NOT NULL INNER JOIN ab.d abd (...)
INNER JOIN a.c ac WITH ac IS NOT NULL (...)

我也尝试合并LEFT JOINS,但没有成功。

长话短说,这是我想要获得的 DQL:

SELECT a FROM model\entity\A a
IF a.b IS NOT NULL INNER JOIN a.b ab WITH (...)
IF a.b IS NULL INNER JOIN a.c ac WITH (...)

我承认我什至不知道这种行为是否可以实现。我认为将其拆分为两个不同的查询会更容易,一个加入$b,另一个加入$c,然后自己合并结果,但我真的很想找到一个单一的查询解决方案(在那里提供是任何)。

感谢您的阅读,以及任何最终的帮助。

干杯!

【问题讨论】:

  • 也许你应该试着解释你为什么想要这个,你想要达到什么目的?我感觉您正在寻找错误问题的解决方案...看起来您需要一个鉴别器字段,请参阅inheritance mapping
  • 在这种情况下,$b 表示另一个实体的一个实例,它具有我需要的其他实体的集合(我们称它们为D)。 $c 表示实体D 的单个实例。问题是如果 $b 有值,我应该使用其集合中包含的 D 对象。或者,如果$b 没有任何值(即为空),我应该直接使用$c(这也是D)。
  • @gummy 你不能选择你的问题作为anwser,但是你可以用一个常规的answer,然后选择它。
  • @Balmipour 感谢您的提示,现在关闭,迟到总比没有好!

标签: php mysql join doctrine-orm dql


【解决方案1】:

您所描述的在SQL中是不可能的,没有条件连接的概念,因为结果集的结构必须是一致的。

DQL 仅在 ORM 映射方面增强 SQL,而不是在添加 SQL 中不存在的功能方面。相反,DQL 不支持 SQL 标准中不存在或在主要 SQL RDBMS 供应商之间没有共同点的 SQL 功能 - 即:大多数供应商不支持或大多数供应商没有等价物。

但是,您可以构建一些 PHP 逻辑来帮助您;例如,您可以使用 Doctrine QueryBuilder 根据使用预取的 PHP 级数据评估的 PHP 级 if 条件构建查询。

例如,您可以运行几个 DQL 查询以从 a.b IS NULL 组和 a.b IS NOT GROUP(分别)预获取 ID,然后继续执行一个或多个查询,以根据这些 ID 获取必要的数据。

【讨论】:

  • 我知道我尝试这样做是不可能的。我只是想确定没有其他办法,因为我知道我做错了。无论如何,正如我在帖子的最新版本中所说,我找到了一种替代方法,通过加入每个需要的实体并检查经典 WHERE 子句中的条件,所有这些都在我想要设计的单个查询中。非常感谢您的洞察力!
【解决方案2】:

找到替代解决方案

因此,在直接在 JOIN 语句中处理条件时,我找不到解决方案。但是,我决定加入我需要的所有实体,并在经典的 WHERE 语句中执行条件检查。

如果有人遇到同样的问题,我是这样解决的:

没用:

SELECT a FROM model\entity\A a
LEFT JOIN a.b ab WITH ab IS NOT NULL INNER JOIN ab.d abd (...)
LEFT JOIN a.c ac WITH ac IS NOT NULL (...)

作品:

SELECT a FROM model\entity\A a
LEFT JOIN a.b ab
LEFT JOIN ab.d abd
LEFT JOIN a.c ac
WHERE ((ab IS NOT NULL AND (...)) OR (ac IS NOT NULL AND (...))) AND (...)

感谢@Balmipour 告诉我如何结束这个话题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多