symfony sub query with getDQL query - php

$sub = $this->entityManager->createQueryBuilder();
$sub->select('d')
->from($this->entityManager->getClassMetadata($entityClass)->getName(), 'd')
->where("d.number != ''")
->orderBy('d.time', 'DESC');
*
$qb = $this->entityManager->createQueryBuilder();
$qb->select('p')
->from($sub->getDQL(),'p')
->groupBy('p.number');
*
Please correct above subqueries if anything is wrong in it.
It is showing error
[Syntax Error] line 0, col 14: Error: Expected Doctrine\ORM\Query\Lexer::T_ALIASED_NAME, got 'SELECT'

Try below code once
$sub = $this->createQueryBuilder('data');
$sub->select('d')
->from($this->getEntityManager()->getClassMetadata($entityClass)->getName(), 'd')
->where("d.number != ''")
->orderBy('d.time', 'DESC');
$qb = $this->createQueryBuilder('data');
$qb->select('p')
->from($sub->getDQL(),'p')
->groupBy('p.number');

Related

Symfony subquery with getDQL throws error

I am trying to convert below query
SELECT * FROM (SELECT * FROM table_name d WHERE d.number != '' ORDER BY d.stop_time DESC ) AS p GROUP BY p.number
with symfony query builder as below =>
$sub = $this->entityManager->createQueryBuilder();
$sub->select('d')
->from($this->entityManager->getClassMetadata($entityClass)->getName(), 'd')
->where("d.number != ''")
->orderBy('d.time', 'DESC');
$qb = $this->entityManager->createQueryBuilder();
$qb->select('p')
->from($sub->getDQL(),'p')
->groupBy('p.number');
I am getting below error =>
[Syntax Error] line 0, col 14: Error: Expected Doctrine\ORM\Query\Lexer::T_ALIASED_NAME, got 'SELECT'
Please correct query if anything wrong in it.
Here is answer
$sub = $this->entityManager->createQueryBuilder();
$sub->select('d.id')
->from($this->entityManager->getClassMetadata($entityClass)->getName(), 'd')
->where("d.number != ''")
->orderBy('d.time', 'DESC');
$qb = $this->entityManager->createQueryBuilder();
$qb->select('p')
->from($this->entityManager->getClassMetadata($entityClass)->getName(), 'p')
->where("p.id IN (".$sub->getDQL().")")
->groupBy('p.number');

Doctrine query SQL to DQL

I have a select with SQL which is working perfectly, but I cannot translate this query to DQL with createQueryBuilder().
Here's my query:
SELECT distinct c.name_id
FROM cultures AS c
LEFT JOIN ilots AS i ON i.exploitation_id = 1
My current code:
return $this->createQueryBuilder('c')
->leftJoin(Ilots::class, 'i', 'ON', 'i.exploitation = 1')
->distinct()
->getQuery()
->getResult();
And the error:
[Syntax Error] line 0, col 74: Error: Expected end of string, got 'ON'
In DQL ON doesn't exist, you have to use WITH instead.
return $this->createQueryBuilder('c')
->leftJoin(Ilots::class, 'i', 'WITH', 'i.exploitation = 1')
->distinct()
->getQuery()
->getResult();
Documentation
If there is relationship between the Entity:
$qb = $this->entityManager->createQueryBuilder('c')
->select('c')
->distinct()
->from('cultures', 'c')
->leftJoin('c.ilots', 'i')
->where('i.exploitation = 1')
;
return $qb->getQuery()->getResult();

use IFNULL in DQL and symfony query

subquery and querybuilder in my project
but when use ```IFNULL`` command in query return eroor
my code is bellow
$subQb = $em->createQueryBuilder();
$subquery = $subQb->select('COUNT(v.id)')
->from('AdminBundle:Visitsite', 'v')
->where('v.site = s.id')
->Andwhere('v.createdate > :date')
->getDQL();
$subQb2 = $em->createQueryBuilder();
$subquery2 = $subQb2->select('l.quantity')
->from('AdminBundle:Limitviewday', 'l')
->where($subQb2->expr()->eq('s.limitviewday', 'l.id'))
->getDQL();
$subQb3 = $em->createQueryBuilder();
$subquery3 = $subQb3->select('COUNT(i.id)')
->from('AdminBundle:Visitsite', 'i')
->where('i.id = s.id')
->Andwhere('i.createdate > :date2')
->Andwhere('i.ip = :ip')
->groupBy('i.ip')
->getDQL();
$subQb4 = $em->createQueryBuilder();
$subquery4 = $subQb4->select('ipl.quantity')
->from('AdminBundle:Iplimitview', 'ipl')
->where('s.iplimitview = ipl.id')
->getDQL();
$qb = $em->createQueryBuilder();
$query = $qb->select('s')
->from('AdminBundle:Sites', 's')
->where('s.quantity > :one')
->Andwhere('s.status = :two')
->Andwhere($qb->expr()->lt("($subquery)", "($subquery2)"))
->Andwhere($qb->expr()->lt("(SELECT IFNULL( ($subquery3),0) )", "($subquery4))"))
->setParameter('one', 1)
->setParameter('two', 1)
->setParameter('date', $date->format('Y-m-d'))
->setParameter('ip', $ip)
->setParameter('date2', $date->format('Y-m-d 00:00:00'));
and my result is
[Syntax Error] line 0, col 274: Error: Expected known function, got
'IFNULL'
Doctrine has limited set of mapped functions, and seems it has no IFNULL by default.
The simple way is to change your DQL and replace IFNULL with IF or COALESCE.
The more difficult way is read manual and implement your own IFNULL mapping like this

Query and subquery in symfony

I use query and subquery in symfony query builder, but when execute it, it returns an error.
My code is :
$subQb = $em->createQueryBuilder();
$subquery = $subQb->select('COUNT(v.id)')
->from('AdminBundle:Visitsite', 'v')
->where('v.site = s.id')
->Andwhere('v.createdate > :date')
->setParameter('date', $date->format('Y-m-d'))
->getDQL();
$subQb2 = $em->createQueryBuilder();
$subquery2 = $subQb2->select('quantity')
->from('AdminBundle:Limitviewday', 'l')
->where($subQb2->expr()->eq('s.limitviewday', 'l.id'))
->getDQL();
$qb = $em->createQueryBuilder();
$query = $qb->select('s')
->from('AdminBundle:Sites', 's')
->where('s.quantity > 1')
->Andwhere('s.status = 1')
->Andwhere($qb->expr()->lte("($subquery)", "($subquery2)"));
$settlements = $query->getQuery()->getResult();
And my result is
[Semantical Error] line 0, col 183 near 'quantity FROM': Error: 'quantity' is not defined.
Please help me.
I think that error come from:
$subquery2 = $subQb2->select('quantity') // Expected '<alias>' or '<alias>.<property>'
instead:
$subquery2 = $subQb2->select('l.quantity')

Subquery in doctrine2 notIN Function

I'd like to select members who are not in specific service. I have 3 tables :
membre
service
membre_service (relation between membre and service)
I'm using doctrine 2 and in SQL my query is :
SELECT m.* FROM membre m WHERE m.`id` NOT IN (
SELECT ms.membre_id FROM membre_service ms WHERE ms.service_id != 29
)
In Doctrine, I do :
$qb = $this->_em->createQueryBuilder();
$qb2 = $qb;
$qb2->select('m.id')
->from('Custom\Entity\MembreService', 'ms')
->leftJoin('ms.membre', 'm')
->where('ms.id != ?1')
->setParameter(1, $service);
$qb = $this->_em->createQueryBuilder();
$qb->select('m')
->from('Custom\Entity\Membre', 'm')
->where($qb->expr()->notIn('m.id', $qb2->getDQL())
);
$query = $qb->getQuery();
//$query->useResultCache(true, 1200, __FUNCTION__);
return $query->getResult();
I got the following error :
Semantical Error] line 0, col 123 near 'm WHERE ms.id': Error: 'm' is already defined.
The same alias cannot be defined 2 times in the same query
$qb = $this->_em->createQueryBuilder();
$qb2 = $qb;
$qb2->select('m.id')
->from('Custom\Entity\MembreService', 'ms')
->leftJoin('ms.membre', 'm')
->where('ms.id != ?1');
$qb = $this->_em->createQueryBuilder();
$qb->select('mm')
->from('Custom\Entity\Membre', 'mm')
->where($qb->expr()->notIn('mm.id', $qb2->getDQL())
);
$qb->setParameter(1, $service);
$query = $qb->getQuery();
return $query->getResult();
Ideally you should use many-to-many relation for your entity, in this case your query is going to be much simpler.
Actually if you are using the Symfony2 repository class you could also do the following:
$in = $this->getEntityManager()->getRepository('Custom:MembreService')
->createQueryBuilder('ms')
->select('identity(ms.m)')
->where(ms.id != ?1);
$q = $this->createQueryBuilder('m')
->where($q->expr()->notIn('m.id', $in->getDQL()))
->setParameter(1, $service);
return $q->getQuery()->execute();
You can use (NOT) MEMBER OF:
<?php
$query = $em->createQuery('SELECT m.id FROM Custom\Entity\Membre WHERE :service NOT MEMBER OF m.services');
$query->setParameter('service', $service);
$ids = $query->getResult();
See the documentation for more examples.

Categories