SQL / Doctrine: проблема левого соединения - PullRequest
5 голосов
/ 15 октября 2010

В настоящее время эта функция работает: она показывает для конкретной игры, сколько рабочих мест существует.

Проблема : если задания нет, игра не появляется в списке.

Как отобразить игру, даже если работа не привязана?

Спасибо

public function getWithGames()
    {
        $q = $this->createQuery('c')
            ->leftJoin('c.stJob j')
            ->where('j.expires_at > ?', date('Y-m-d h:i:s', time()))
            ->addOrderBy('c.name');

        $q->andWhere('j.is_activated = ?', 1);
        $q->andWhere('j.is_public = ?', 1);


        return $q->execute();
    }

Ответы [ 2 ]

10 голосов
/ 15 октября 2010

Ваши условия должны быть частью предложения LEFT JOIN ... ON.

$q = $this->createQuery('c')
    ->leftJoin('c.stJob j WITH j.expires_at > ? AND j.is_activated = 1 AND j.is_public = 1', date('Y-m-d h:i:s', time()))
    ->addOrderBy('c.name');

Помещение условий в условие ON (в отличие от WHERE) указывает, что они применяются конкретно к JOIN. Если ни одна строка не удовлетворяет этим условиям, соединение отсутствует - и это именно то, что вам нужно в этом случае. Помещение их в WHERE означает, что строки result должны удовлетворять этим условиям. И очевидно, что если не было объединения, вы не можете удовлетворить любые условия относительно таблицы j.

1 голос
/ 15 октября 2010
$q->andWhere('j.is_activated = ?', 1);
$q->andWhere('j.is_public = ?', 1);

если нет работы, его is_activation и поле is_public не могут быть 1. оно будет нулевым, поэтому вам нужно что-то вроде: where (j.is_activated = 1 and j.is_activated = 1) or (j.is_activated = IS NULL and j.is_activated IS NULL) ...

я не знаю, какой библиотекарь выиспользуют для создания этого запроса, но я думаю, он может работать так:

public function getWithGames()
    {
        $q = $this->createQuery('c')
            ->leftJoin('c.stJob j')
            ->where('j.expires_at > ?', date('Y-m-d h:i:s', time()))
            ->addOrderBy('c.name');

        $q->andWhere('(j.is_activated = ? AND j.is_public = 1) OR (j.is_activated IS NULL  AND j.is_publicIS NULL )', 1);

        return $q->execute();
    }

это не красиво ... но, как я сказал, я не знаю вашу библиотеку.Вы могли бы, вероятно, передать массив аргументов или сделать что-то вроде "orWhere ...." blabla ...

способ, которым это делается, также неуклюже и может быть сделано лучше.Используйте условия напрямую, чтобы установить соединение!таким образом вы избегаете объединения целых таблиц и последующей фильтрации ...

...