Currently I have this DQL query which I want to rewrite with a QueryBuilder, but because I play several entities it is complicated, I have seen examples but I do not understand how more than one entity is related to the code I want to rewrite is the following:
Public function getDepartamentoEmpresaEmpleado($numdoc){
// Muestra todos los departamentos de la empresa a la cual pertenece el empleado logeado
$em = $this->getEntityManager();
$empresa_repo = $em->getRepository('BackendBundle:Empresa');
$idempresa = $empresa_repo->getVerIdempresa($numdoc);
$dql = "SELECT a FROM BackendBundle:DepartamentoRrhh a
INNER JOIN BackendBundle:CentroCosto b WITH a.idcentroCosto = b.idcentroCosto
INNER JOIN BackendBundle:Empresa c WITH b.idempresa = c.idempresa
WHERE c.idempresa = :idempresa";
$query = $em->createQuery($dql)->setParameter('idempresa', $idempresa);
$Departamentos = $query->getResult();
return $Departamentos;
}
Try this,
Add this in the repository of DepartamentoRrhh entity
public function getDepartamentoEmpresaEmpleado($numdoc){
$em = $this->getEntityManager();
$idempresa = $em->getRepository('BackendBundle:Empresa')->getVerIdempresa($numdoc);
$query = $this->createQueryBuilder('a')
->innerJoin('a.idcentroCosto', 'b')
->innerJoin('b.idempresa', 'c')
->where('c.idempresa = :idempresa')
->setParameter('idempresa', $idempresa)
->getQuery();
$Departamentos = $query->getResult();
return $Departamentos;
}
Hope this will work.
This should work
$Departamentos = $empresa_repo->createQueryBuilder('a')
->innerJoin('a.idcentroCosto', 'b')
->innerJoin('b.idempresa', 'c')
->andWhere('c.idempresa = :idempresa')
->setParameter('idempresa', $idempresa)
->getQuery()
->getResult();
There is no need to specify Entity when doing innerJoin because
doctrine already knows about it through the entity mapping.
Related
I realized this sql which works without problems
SELECT meeting.name, meeting.date, community.name, participation.isPresent, participation.user_id
FROM meeting
INNER JOIN community
ON meeting.community_id = community.id
AND community.is_active = 1
LEFT join participation
ON meeting.id = participation.meeting_id
AND participation.user_id = 1078
WHERE meeting.date >= CURRENT_DATE()
ORDER BY meeting.date DESC
I'm trying to reproduce it with the doctrine query builder but I never got the right result. The user id part doesn't seem to be part of the leftJoin function but is applied to the request globally, which is not what I want.
public function getNextMeetings()
{
$qb = $this->createQueryBuilder('m')
->select('m.name AS meeting, m.date, c.name AS community, p.isPresent', 'IDENTITY(p.user) AS user')
->innerJoin('m.community', 'c')
->where('c.isActive = true')
->leftJoin('m.participations', 'p')
//->leftJoin('p.user', 'u')
//->where('u.id = 1078 OR u.id IS NULL')
//->where('IDENTITY(p.user) = 1078')
->andWhere('m.date >= CURRENT_DATE()')
->orderBy('m.date', 'DESC');
return $qb->getQuery()->execute();
}
My comments are what I tried to fix this issue.
Check Working with QueryBuilder: High level API methods
More precisely, the definition od leftJoin() function:
public function leftJoin($join, $alias, $conditionType = null, $condition = null, $indexBy = null);
You can place a condition on the joined Entity by:
use Doctrine\ORM\Query\Expr;
->leftJoin('m.participations', 'p', Expr\Join::WITH, 'p.user = :userId')
->setParameter('userId', 1078)
Note you do not need a condition for "meeting.id = participation.meeting_id", as this is autoapplied by the relation m.participations to the join constructed.
How could I write this sql query on symfony query builder syntax?
Analysis, Region, Nature and Garden are Entities
SELECT * FROM `analysis`
INNER JOIN sample ON sample.id = analysis.sample_id
INNER JOIN region ON sample.region_id = region.id
INNER JOIN nature ON sample.nature_id = nature.id
INNER JOIN garden ON sample.garden_id = garden.id
WHERE sample.stateProduct = 'Origin'
AND analysis.status = '0'
AND region.name = 'Jangsu'
AND garden.name = 'North Tukvar'
AND nature.name = 'Thé Vert'
AND sample.sampleBio = '1'
AND sample.supplierCountry = 'Inde'
I tried this way but, I don't have error msg, but it's not same result as sql query.
public function countAnalysisByCriteria($stateProduct, $status, Nature $nature, Region $region, Garden $garden, $supplierName, $bio, $country, $startDate, $endDate){
$qb = $this->createQueryBuilder('analysis')
->addSelect('count(analysis) as result')
->innerJoin('analysis.sample', 'sample', 'WITH', 'analysis.sample = sample')
->innerJoin('sample.nature', 'nature', 'WITH', 'sample.nature = :nature')
->innerJoin('sample.region', 'region', 'WITH', 'sample.region = :region')
->innerJoin('sample.garden', 'garden', 'WITH', 'sample.garden = :garden')
->groupBy('result');
->andWhere('sample.stateProduct = :stateProduct');
->setParameter('stateProduct', $stateProduct);
->andWhere('sample.nature = :nature');
->setParameter('nature', $nature);
->andWhere('sample.region = :region');
->setParameter('region', $region);
->andWhere('sample.garden = :garden');
->setParameter('garden', $garden);
->andWhere('sample.dateReception BETWEEN :startDate AND :endDate');
$qb->setParameter('startDate', $startDate);
$qb->setParameter('endDate', $endDate);
}
return $qb->getQuery()->getArrayResult();
Your code snippet is completely wrong, try the following:
use Doctrine\ORM\Query\Expr\Join;
public function countAnalysisByCriteria(
$stateProduct,
$status,
Nature $nature,
Region $region,
Garden $garden,
$supplierName,
$bio,
$country,
$startDate,
$endDate
) {
$qb = $this->createQueryBuilder();
return $qb->select('count(analysis) as result')
->innerJoin('analysis.sample', 'sample', Join::WITH, 'analysis.sample = sample.id')
->innerJoin('sample.nature', 'nature', Join::WITH, 'sample.nature = nature.id')
->innerJoin('sample.region', 'region', Join::WITH, 'sample.region = region.id')
->innerJoin('sample.garden', 'garden', Join::WITH, 'sample.garden = garden.id')
->groupBy('result')
->andWhere('sample.stateProduct =:stateProduct')
->setParameter('stateProduct', $stateProduct)
->andWhere('sample.nature =:nature')
->setParameter('nature', $nature)
->andWhere('sample.region =:region')
->setParameter('region', $region)
->andWhere('sample.garden =:garden')
->setParameter('garden', $garden)
->andWhere('sample.dateReception BETWEEN :startDate AND :endDate')
->setParameter('startDate', $startDate)
->setParameter('endDate', $endDate)
->getQuery()
->getArrayResult();
}
DO NOT add spaces on assignments = : (wrong), =: (right)
Check your code properly, notice how I have removed some colon ; at some pieces because does not make sense have them there.
the goal of this query is to show records from table orders that don't have any shipments created yet. Here is how it should be done in SQL:
SELECT *
FROM orders
LEFT JOIN orders_shipments shipments ON orders.trx_id = shipments.trx_id
WHERE shipments.shipment_id IS NULL
AND orders.purchase_date IS NOT NULL
AND orders.fulfillment_channel = 'MFN';
The following query shows 0 results. Vs the following:
$qb = $this->createQueryBuilder('orders');
$qb->select('orders, shipments')
->leftjoin('orders.shipments', 'shipments')
->Where('shipments.id IS NULL')
->ANDWhere('orders.purchaseDate IS NOT NULL')
->ANDWhere('orders.fulfillmentChannel = :a')->setParameter('a', 'MFN');;
$results = $qb->getQuery()
->getResult();
return $results;
Does show results. Why is that and how to fix it?
Not sure why but I had to use GROUP and HAVING to get it to work:
$qb = $this->createQueryBuilder('orders');
$qb->select('orders, shipments')
->leftjoin('orders.shipments', 'shipments')
->Where('shipments.id IS NULL')
->ANDWhere('orders.purchaseDate IS NOT NULL')
->ANDWhere('orders.fulfillmentChannel = :a')->setParameter('a', 'MFN')
->GroupBy('orders.id')
->having('count(shipments) = 0');
$results = $qb->getQuery()->getResult();
My colons are never transformed into the parameters value
$queryBuilder
->select('p.id', 'p.quantite', 'p.dateAjoutPanier', 'p.prix, p.user_id', 'v.nom', 'p.produit_id')
->from('paniers', 'p')
->innerJoin('p', 'produits', 'v', 'p.produit_id=v.id')
->where('p.user_id = :userid')
->andWhere('p.produit_id = :produitid')
->setParameter('produitid',(int)1)
->setParameter('userid',(int)1);
return $queryBuilder->getSQL();
this code return :
SELECT p.id, p.quantite, p.dateAjoutPanier, p.prix, p.user_id, v.nom, p.produit_id FROM paniers p INNER JOIN produits v ON p.produit_id=v.id WHERE (p.user_id = :userid) AND (p.produit_id = :produitid)
Someone have the problem (or the solution) ?
If you have selected more than one rows you should use the loop to iterate over each key - value entity.
But if you have only one row, use getSingleResult() or getOneOrNullResult() methods with setMaxResults(1)
For example:
$queryBuilder
->select('p.id', 'p.quantite', 'p.dateAjoutPanier', 'p.prix, p.user_id', 'v.nom', 'p.produit_id')
->from('paniers', 'p')
->innerJoin('p', 'produits', 'v', 'p.produit_id=v.id')
->where('p.user_id = :userid')
->andWhere('p.produit_id = :produitid')
->setParameter('produitid',1)
->setParameter('userid',1)
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
when i define a parameter in the given section its give me error that this "tt" parameter is undefine. i do not know what is the problem. it give me this error
Notice: Undefined property: Doctrine\ORM\QueryBuilder::$SELECT u1.unitid, m1.id FROM ApiMapBundle:Mappaths m1 INNER JOIN ApiMapBundle:Unitids u1 WITH m1.refUnitids2 = u1.id OR m1.refUnitids1 = u1.id WHERE m1.id=:tt
$cn=2;
$qb = $em->createQueryBuilder();
$query = $qb->select('u1.unitid','m1.id')
->from('ApiMapBundle:Mappaths', 'm1')
->join('ApiMapBundle:Unitids', 'u1', 'WITH', $qb->expr()->orX('m1.refUnitids2 = u1.id', 'm1.refUnitids1 = u1.id'))
->andWhere('m1.id=:tt')
->$qb->setParameter('tt', $cn)
->getQuery()
->getResult();
return $query;
any idea?
Try removing ->$qb from ->$qb->setParameter('tt', $cn)