doctrine querybuilder $qb -> expr()-> all - symfony

I'm working with Symfony2. I have to list last $nbOpe entities of Entity OpeEntetes. The following script gives me error:
Blockquote
[Doctrine\ORM\Query\QueryException]
[Semantical Error] line 0, col 16 near 'ALL(SELECT FROM': Error: Class 'ALL' is not defined.
Blockquote
What to do ?
public function essai1($nbOpe){
$in = $this->_em->createQueryBuilder()
->from('GcRequetesBundle:OpeEntetes','ein')
->orderBy('ein.oeNumOpe', 'DESC')
->setMaxResults($nbOpe);
$qb = $this->_em->createQueryBuilder();
$qb
-> add("select",new Expr\Select(array('res')))
-> add('from', new Expr\From($qb -> expr()-> all($in -> getDql()), 'res'));
$query = $qb -> getQuery();
$result= $query -> getArrayResult();
return $result;
}

There are couple of errors in your code:
subqueries do no support setMaxResults Enabling LIMIT resp. setMaxResults on subquery
from field does not support subqueries Subquery into FROM
you have probably misunderstood what the ALL expression means and for what it is used for For example MySql documentation about ALL
In any case, the restriction that subqueries do not support the setMaxLimits probably means that you cannot build your code in this way at all. If that isn't a show-stopper for you, then you could try it with the following code for example (easiest would be to just have one query, but I assume you have some reason for doing this in two steps...):
$in = $em->createQueryBuilder()
->select('ein')
->from('GcRequetesBundle:OpeEntetes','ein')
->orderBy('ein.oeNumOpe', 'DESC')
->setMaxResults($nbOpe); // this does not affect the result at all
$qb = $em->createQueryBuilder();
$qb->add('select', 'ein2');
$qb->add('from', 'GcRequetesBundle:OpeEntetes ein2');
$qb->add('where', $qb->expr()->eq('ein2.id', $qb->expr()->any($in->getDql())));
$query = $qb -> getQuery();
$result= $query -> getArrayResult();
return $result;

Related

Howto Write normal sentence in SQL

I want to write this sentence for DQL :
SELECT id FROM `article` WHERE `created_at` IN (select max(created_at) from article)
I try this one but i have some error :
return $this->createQueryBuilder('p')
->select('p.id')
->where('p.createdAt IN (select max(p.createdAt)from p)')
->getQuery()
->getResult();
Error :
[Semantical Error] line 0, col 88 near 'p)': Error: Class 'p' is not defined.
Thanks a lot,
ibynmax
You'll also need to write out the subquery in the query builder:
$subQuery = $this->createQueryBuilder('p')
->select('max(p.createdAt)');
$queryBuilder = $this->createQueryBuilder('p');
return $queryBuilder
->select('p.id')
->where($queryBuilder->expr()->in('p.createdAt', $subQuery->getDQL()))
->getQuery()
->getResult();

DISTINCT Statement is not working in Doctrine

I try get distinct rows from doctrine, but it not work (uniq hotels)
$qb = $this->createQueryBuilder('self');
$qb
->distinct('hotel')
->join('self.hotel', 'hotel')
->where('self.request = :id')
->setParameter('id',$requestId);
return $qb->getQuery()->getResult();
This DQL returns all hotels.
SQL qwery from Symfony:
I want this qwery:
SELECT count(DISTINCT hotel_id) FROM symfony.search_result where request_id=#requrst_id
Based on your update the DQL you want to build is this
$qb = $this->createQueryBuilder('self');
$qb
->select($qb->expr()->countDistinct('hotel.id'))
->join('self.hotel', 'hotel')
->where('self.request = :id')
->setParameter('id',$requestId);
return $qb->getQuery()->getSingleScalarResult();
note that i changed the
->distinct('hotel') to ->select($qb->expr()->countDistinct('hotel.id'))
also i changed the
getResult() to getSingleScalarResult()
now it will return just one result with the count of the unique hotel_ids

Doctrine : SELECT a relationned entity

I have 2 entities :
LinkServInfra
Serv
LinkServInfra entity :
id
serv (relation OneToOne to Serv)
infra (ManyToOne to another entity)
Now, I'd like to get a list of Serv based on infra.
So I tried in LinkServInfraRepository :
$qb = $this->createQueryBuilder('s')
->select('DISTINCT s.serv')
->where('s.infra = :infra')
->setParameter('infra', $infra);
return $qb->getQuery()->getResult();
And I get an error :
[Semantical Error] near 'serv FROM': Error: InvalidPathExpression.
Must be a StateFieldPathExpression.
(I tried first without DISTINCT and tried with it based on answer found here).
The query seems to be good because it's :
SELECT DISTINCT s.serv
FROM MyBundle\Entity\LinkServInfra s
WHERE s.infra = :infra
How would you do?
Thanks!
Since the relation is ONLY in LinkServInfra and not in Serv :
I used the relation in LinkServInfra to do it...
public function filter($type, $etat, $infra){
$qb = $this->createQueryBuilder('l');
$qb->where(' l.infra = :infra ')
->setParameter('infra', $infra);
if( $type || $etat ){
$qb->join('l.serv', 's')
//where & setParameter for type
//where & setParameter for detail
}
And then where I call the function filter :
$entities = $em->getRepository('linkServInfra')->filter(//...
$servs = array();
foreach($entities as $entity){
$servs[] = $entity->getServ();
}
I guess it's not the cleanest solution but it's working...
I think you can not use DISTINCT on a relation, only for the root entity alias.
You should use Serv entity as root and join with LinkServInfra and infra entity through the 2nd. Something like:
$qb = $this->getDoctrine()
->getRepository(Serv::class)->createQueryBuilder('s')
->select('DISTINCT s')
->leftJoin("s.linkServInfra", "lsi")
->leftJoin("lsi.infra", "infra")
->where('infra.id = :infra')
->setParameter('infra', 1);
Alternatively, if the relation is unidirectional and you do not want to make it bidirectional, you can use a custom join:
use Doctrine\ORM\Query\Expr\Join;
$qb = $this->getDoctrine()
->getRepository(Serv::class)->createQueryBuilder('s')
->select('DISTINCT s')
->leftJoin(LinkServInfra::class, "lsi", Join::WITH, 'lsi.serv = s')
->leftJoin("lsi.infra", "infra")
->where('infra.id = :infra')
->setParameter('infra', 1);
References
How to JOIN without a relationship in Doctrine?

query with dateformat in where clause in symfony2

when I run a query with date in where clause, following error is showed...
[Syntax Error] line 0, col 129: Error: Expected known function, got 'DATE_FORMAT'
the query is given below
$query = $this->getEntityManager()->createQuery(
"SELECT a.id, a.amont, a.paymentDescrip, a.paymentType, a.paymentDate
FROM RegalSmsBundle:DailyTransaction a
WHERE DATE_FORMAT(a.paymentDate,'%Y-%m-%d') = :paymentDate
and a.students = :studentId"
)->setParameter('studentId', $studentId)
->setParameter('paymentDate','2013-03-11');
return $query->getResult();
Doctrine doesn't have DATE_FORMAT function defined by default. It's possible to Register Custom DQL Function.
But you can compare date easily (assuming a.paymentDate is of type date):
$query = $this->getEntityManager()->createQuery("
SELECT a.id, a.amont, a.paymentDescrip, a.paymentType, a.paymentDate
FROM RegalSmsBundle:DailyTransaction a
WHERE a.paymentDate = :paymentDate AND a.students = :studentId
")
->setParameter('studentId', $studentId)
->setParameter('paymentDate', new \DateTime('2013-03-11'))
;
return $query->getResult();
Edit: I prefer using querybuider to writing DQL. It would look like this:
$qb = $this->getEntityManager()->getRepository('RegalSmsBundle:DailyTransaction')->createQueryBuilder('a');
$qb
->select('a') // select whole entity
->where($qb->expr()->andX(
$qb->expr()->eq('a.paymentDate', ':paymentDate')
$qb->expr()->eq('a.students', ':studentId')
))
->setParameter('studentId', $studentId)
->setParameter('paymentDate', new \DateTime('2013-03-11'))
;
return $qb->getQuery()->getResult();

'where not in' query with doctrine query builder

Im trying to reproduce this query:
SELECT * FROM `request_lines`
where request_id not in(
select requestLine_id from `asset_request_lines` where asset_id = 1
)
in doctrine query builder,
I am stuck on the where request_id not in(select
I currently have:
$linked = $em->createQueryBuilder()
->select('rl')
->from('MineMyBundle:MineRequestLine', 'rl')
->where()
->getQuery()
->getResult();
You need to use query builder expressions, and this means you need access to the query builder object. Also, the code is easier to write if you generate the subselect list ahead of time:
$qb = $em->createQueryBuilder();
$nots = $qb->select('arl')
->from('$MineMyBundle:MineAssetRequestLine', 'arl')
->where($qb->expr()->eq('arl.asset_id',1))
->getQuery()
->getResult();
$linked = $qb->select('rl')
->from('MineMyBundle:MineRequestLine', 'rl')
->where($qb->expr()->notIn('rl.request_id', $nots))
->getQuery()
->getResult();
It is possible to do this in one Doctrine query:
$qb = $this->_em->createQueryBuilder();
$sub = $qb;
$sub = $qb->select('arl')
->from('$MineMyBundle:MineAssetRequestLine', 'arl')
->where($qb->expr()->eq('arl.asset_id',1));
$linked = $qb->select('rl')
->from('MineMyBundle:MineRequestLine', 'rl')
->where($qb->expr()->notIn('rl.request_id', $sub->getDQL()))
->getQuery()
->getResult();
Check the reference in this answer here
Using Symfony 5, this solution might help those, who are trying to set parameters on a subquery, the notIn() 2nd argument accepts an array or you could pass a DQL instead and that's what we are doing here and keep in mind that the parameters should be added to the main query as below.
$main = $this->em->createQueryBuilder();
$sub = $main;
$sub = $sub->select('arl')
->from('$MineMyBundle:MineAssetRequestLine', 'arl')
->where($sub->expr()->eq('arl.asset_id',':id'));
$linked = $main->select('rl')
->from('MineMyBundle:MineRequestLine', 'rl')
->where($main->expr()->notIn('rl.request_id', $sub->getDQL()))
->setParameter('id', 1)
->getQuery()
->getResult();

Resources