Доктрина 2: как вы используете столбец подзапроса (в предложении SELECT)
Я пытаюсь сделать простой запрос select с подзапросом в предложении SELECT и просто не нашел способ сделать это. Я пробовал как с DQL, так и с QueryBuilder, не работает. Код следует, пожалуйста, не говорите, что я могу просто использовать соединение, это упрощенный пример, чтобы проиллюстрировать проблему, у меня есть законные варианты использования для подзапросов.
// With QueryBuilder
$query = $qb->select(array('a',
'(SELECT at.addresstypeName
FROM e:Addresstype at
WHERE at.addresstypeId = a.addresstypeId
) AS addresstypeName'))
->from('e:Address', 'a')
->where('a.addressId = :addressId')
->setParameter('addressId', 1);
// With DQL
$dql = "SELECT a,
(SELECT at.addresstypeName
FROM e:Addresstype at
WHERE at.addresstypeId = a.addresstypeId
) AS addresstypeName
FROM e:Address a
WHERE a.addressId = :addressId";
$query = $em->createQuery($dql)->setParameter(':addressId', 1);
В таблице Address указано следующее соотношение:
/**
* @ORM\ManyToOne(targetEntity="Addresstype")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="addresstype_id", referencedColumnName="addresstype_id")
* })
*/
protected $addresstype;
В исходном SQL запрос будет выглядеть так:
SELECT
a.*,
(
SELECT at.addresstype_name
FROM addresstype at
WHERE at.addresstype_id = a.addresstype_id
) AS addresstype_name
FROM address a
WHERE a.address_id = 1
Любые идеи?
Ответы
Ответ 1
$query = $qb->select('a')
->addSelect('(SELECT at.addresstypeName
FROM e:Addresstype at
WHERE at.addresstypeId = a.addresstypeId) AS addresstypeName'
)
->from('e:Address', 'a')
->where('a.addressId = :addressId')
->setParameter('addressId', 1);
Ответ 2
Для меня подзапрос с доктриной работает с этим запросом:
$qb->select('e.field')
->addSelect('(SELECT count(mv.nm)
FROM Clt\Bundle\MyBundle\Entity\MV mv
LEFT JOIN Clt\Bundle\MyBundle\Entity\M ma WITH mv.nm=ma.nm
WHERE mv.ne=e.ne and ma.nm is null
) AS nm'
)
->from($this->_entityName, 'e')
->leftJoin('e.m', 'm')
->where($qb->expr()->eq('t.id'.$typeModule, $idElementModule));
Обратите внимание, что в левом соединении вы должны использовать WITH вместо ON...