我正在尝试使用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);
在地址表中定义了以下关系:
/**
* @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
有什么想法吗?
答案 0 :(得分:20)
$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);
答案 1 :(得分:11)
对于我来说,带有学说的子查询适用于此查询:
$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 ...
答案 2 :(得分:1)
在我的场景中,我需要查看一个联接并找到一个ID并将其用作布尔值,找到1否则为0,然后将其应用于orderBy。 DQL表达式仅在与Where子句结合使用时才有效,这不是我的情况。因此,DQL子选择保存了我。
或多或少地适应您的情况,看起来像这样:
// With QueryBuilder
// In AddressRepository
// Where one address may belong to several addressTypes
public function getWithType($addressType){
$qb = $this->createQueryBuilder('a1');
$qb->addSelect('a1.someField', 'a1.otherField')
$qb->addSelect(
'(SELECT at.addressTypeName
FROM App\Entity\Address a2
JOIN a2.addressType at
WHERE at.id = '.$addressType.' AND a2.id = a1.id
) AS addressTypeName')
//The rest part of the query
}
答案 3 :(得分:0)
我知道这是一个老问题,但是如果您愿意,可以使用其他查询构建器作为子查询:
$qb->select("a")
->addSelect("(" . $qb2->select("at.addresstypeName")
->from("e:Addresstype", "at")
->where("at.addresstypeId = a.addresstypeId")
->getDQL() . ") AS addresstypeName"
)
->from('e:Address', 'a')
->where('a.addressId = :addressId')
->setParameter('addressId', 1);