Query and subquery in symfony - php

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')

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');

symfony sub query with getDQL query

$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');

error In sub query in symfony

subquery and querybuilder in my project but result is error
my dql code is
$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.site = 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("(COALESCE( ($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'));
$settlements = $query->getQuery()->getResult();
and my result dql is
SELECT s FROM AdminBundle:Sites s WHERE s.quantity > :one AND s.status = :two AND ((SELECT COUNT(v.id) FROM AdminBundle:Visitsite v WHERE v.site = s.id AND v.createdate > :date) < (SELECT l.quantity FROM AdminBundle:Limitviewday l WHERE s.limitviewday = l.id)) AND ((COALESCE( (SELECT COUNT(i.id) FROM AdminBundle:Visitsite i WHERE i.site = s.id AND i.createdate > :date2 AND i.ip = :ip GROUP BY i.ip),0) ) < (SELECT ipl.quantity FROM AdminBundle:Iplimitview ipl WHERE s.iplimitview = ipl.id)))
every ting is ok but my result is error
[Syntax Error] line 0, col 279: Error: Expected Literal, got 'SELECT'
Your output sql is SELECT s FROM AdminBundle:Sites but it is wrong.
correction is
SELECT *FROM AdminBundle:Sites
s is not field, should be use before FROM column name like s.quantity, s.stauts like that
Please edit your code in this like : $query = $qb->select('s') change select 's' link above instruction

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

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