Search code examples
phpmysqljoindoctrine-ormdql

Doctrine Conditional joins


I'm trying to figure out how to achieve conditional joins in doctrine.

I have an entity A with two fields, let's call them b (referencing a single Bobject) and c (referencing a single C object) respectively.

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

I want to write a DQL query which is going to perform an INNER JOIN on $b ONLY if $b is not null, and if $b is null the INNER JOIN should be applied to$c instead (if $c is not null too).

I tried combining INNER JOINS with WITH clauses checking for null values, but this doesn't work obviously.

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 (...)

I also tried combining LEFT JOINS without success.

Long story short, here's the kind of DQL I'd like to obtain :

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 (...)

I'll admit I don't even know if that kind of behaviour is achievable. I think it would be easier to split this into two distinct queries, one joining on $b and the other joining on $c then merging the results myself, but I'd really like to find a single-query solution (provided there is any).

Thanks for reading, and for any eventual help.

Cheers!


Solution

  • Alternative solution found

    So I couldn't find a solution while working with conditions directly in the JOIN statements. However, I decided to join all the entities I needed, and perform the condition checks in a classic WHERE statement.

    If anyone runs into the same kind of issue, here's how I solved this :

    Doesn't work :

    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 (...)
    

    Works :

    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 (...)
    

    Thanks @Balmipour for telling me how to close this topic.