Я пытаюсь понять, как добиться условного объединения в учении.
У меня есть сущность A
с двумя полями, давайте назовем их b
(ссылаясь на один B
объект) и c
(ссылаясь на один C
объект) соответственно.
/**
* @Entity
**/
class A
{
/** @ManyToOne(targetEntity="B") **/
protected $b;
/** @OneToOne(targetEntity="C") **/
protected $c;
}
Я хочу написать запрос DQL, который собирается выполнить INNER JOIN
на $b
Только если $b
не является нулевым, и если $b
является нулевым INNER JOIN
следует применять к$c
вместо (если $c
тоже не нуль).
Я пробовал комбинировать INNER JOINS
с WITH
пункты, проверяющие нулевые значения, но это, очевидно, не работает.
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
затем объединить результаты самостоятельно, но мне бы очень хотелось найти решение с одним запросом (если оно есть).
Спасибо за чтение и за любую возможную помощь.
Поэтому я не мог найти решение, работая с условиями непосредственно в 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 (...)
Поскольку я не могу выбрать свой пост в качестве ответа, я думаю, он останется открытым ..?
Ура!
То, что вы описываете, невозможно в SQL, нет концепции условных объединений, потому что структура результирующего набора должна быть согласованной.
DQL только улучшает SQL в отношении сопоставления ORM, а не в отношении добавления функций, отсутствующих в SQL. Напротив, DQL не поддерживает функции SQL, которых нет в стандартах SQL или которые не имеют общего с основными поставщиками СУБД SQL, т. Е. Которые не поддерживаются большинством поставщиков или не имеют аналогов в большинстве поставщиков.
Тем не менее, вы можете создать некоторую логику PHP, чтобы помочь вам в этом; например, вы можете использовать Doctrine QueryBuilder для построения запроса на основе уровня PHP if
условия оцениваются с использованием предварительно извлеченных данных уровня PHP.
Например, вы можете выполнить несколько запросов DQL, чтобы предварительно извлечь идентификаторы из a.b IS NULL
группа и a.b IS NOT GROUP
(отдельно), а затем продолжите один или несколько запросов, извлекающих необходимые данные на основе этих идентификаторов.
Других решений пока нет …