2013-06-12 3 views
1

Объект «актив» связан с «logEntries». Может быть 0..N записей журнала для каждого актива.Symfony2, doctrine2 & querybuilder: выбор последнего объекта ассоциации, если он доступен

Часть каждой записи в журнале - это поле (или свойство) "status". Текущее состояние каждого актива определено в его последней записи в журнале. Если нет записей в журнале, связанных с активом, его статус неизвестен.

В настоящее время я рассчитываю активы для каждого состояния. Пример состояния: «доступно».

Проблема заключается в том, что:

  • либо активы посчитаны более чем один раз, если они имели чередующиеся значения статуса в прошлом (что они в значительной степени все делают)
  • или, я получаю ошибка, потому что я ищу последнюю запись в журнале для каждого актива, но некоторые активы не имеют записей журнала и агрегатная функция в DQL не удается

Я пытаюсь следующий код:

$qb = $this->_em->createQueryBuilder(); 
$qb->select('COUNT(a)') 
    ->from('AppAssetBundle:Asset', 'a') 
    ->leftJoin('a.logEntries', 'l') 
    ->where('l.status = '.$status_id) 
    ->andWhere('l.id = MAX(l.id)') 
; 
return $qb->getQuery()->getSingleScalarResult(); 

Ошибка:

SQLSTATE[HY000]: General error: 1111 Invalid use of group function

Замена ->andWhere() на ->having() не работает.

Кто-нибудь знает, как получить последнее лицо ассоциации, , если оно есть?

Если нет связанных полей, я хотел бы весь мой запрос возвращает 0 вместо ошибки :)

ответ

1

Если я правильно понимаю вашу проблему правильно, вы не могли бы просто добавить поле createdAt в Assocation лица например:

/** 
* @ORM\Entity() 
* @ORM\HasLifecycleCallbacks() 
*/ 
class YourClass 
{ 
    protected $asset_id; 

    protected $log_id; 

    /** 
    * @ORM\Column(type="datetime") 
    */ 
    protected $createdAt; 

    /** 
    * @ORM\PrePersist 
    */ 
    public function prePersist() 
    { 
     $this->createdAt = new \DateTime('now'); 
    } 
} 

Тогда вы можете просто отсортировать по дате и получить последнюю запись.

+1

Существует поле createdAt, но не могу ли я захватить наивысший идентификатор или самую последнюю дату, не имеет значения для проблемы. Проблема заключается в следующем: как я могу получить последнюю запись в запросе? И если эта последняя запись не относится к статусу, который я ищу, или он не существует, поскольку нет связанных записей, COUNT() должен возвращать 0. –