Doctrine2 LEFT JOIN exception - php

I've got a problem with Symfony/Doctrine2 doing SQL statement with two entites:
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('s')
->from('basecomProductionWorkflowBaseBundle:SubprocessData', 's')
->leftJoin('basecomProductionWorkflowBaseBundle:ReleaseDay', 'r', Expr\Join::WITH, 'r.id = s.releaseDay')
->where(
$qb->expr()->andX(
$qb->expr()->eq('r.date', ':date'),
$qb->expr()->isNotNull('r.edition')
)
)
->setParameter('date', $date);
I got the following error message:
[Semantical Error] line 0, col 124 near 'r WITH r.id =': Error: Identification Variable basecomProductionWorkflowBaseBundle:ReleaseDay used in join path expression but was not defined before.
PS: Both tables have no relation to each other (it's a workaround fixing another problem). I've tested the same statement in phpmyadmin.

It should be:
->leftJoin('s.releaseDay', 'r')
You could also simplify the conditions this way:
->where('r.date = :date')
->andWhere('r.edition IS NOT NULL')
or:
->where('r.date = :date AND r.edition IS NOT NULL')

¿What Expr class are you using?
I choose incorrectly the Expr class some days ago and throw me same exception.
Try:
use Doctrine\ORM\Query\Expr;

Related

DQL select all users and count the number of reservations of each

I'm trying to select all my users and, for each user, count the number of reservations made and incoming. For the moment I have this
$qb = $this->createQueryBuilder('user');
return $qb->select('user')
->leftJoin('user.reservations', 'reservations')
->leftJoin('reservations.marketDate', 'market_date')
->addSelect('COUNT(nb_reservations FROM reservations WHERE market_date.date >= CURRENT_DATE())')
->orderBy('user.name')
->groupBy('user.id')
->getQuery()
->getResult();
But I have this error
[Semantical Error] line 0, col 59 near 'market_date >=': Error: Class
'market_date' is not defined.
Please help me
Try this:
$qb = $this->createQueryBuilder('user');
return $qb->select('user, count(reservations) as count')
->leftJoin('user.reservations', 'reservations')
->leftJoin('reservations.marketDate', 'market_date')
->where('market_date.date >= CURRENT_DATE()')
->orderBy('user.name')
->groupBy('user.id')
->getQuery()
->getResult();
The syntax in the COUNT does not seem correct: the COUNT should not include the whole statement. Try this:
->addSelect('COUNT(nb_reservations) FROM reservations WHERE market_date.date >= CURRENT_DATE()')

How to do a select query in LeftJoin querybuilder

How can I convert below query to Doctrine:
SELECT restaurants.restaurant_name ,
restaurants.restaurant_id,
j.LASTPRICE
FROM restaurants
LEFT JOIN
(
SELECT f.food_id AS fid,
f.restaurants_restaurant_id AS rid,
Max(f.food_last_price) AS LASTPRICE
FROM foods AS f
LEFT JOIN restaurants AS r
ON r.restaurant_id = f.restaurants_restaurant_id
WHERE f.food_last_price IS NOT NULL
GROUP BY r.restaurant_id) j
ON restaurants.restaurant_id = j.rid
Here is my code:
$qb = $this->_em->createQueryBuilder();
$qb2 = $this->_em->createQueryBuilder();
$getMaxPercentage = $qb2
->select(
'MAX (Food.foodLastPrice) AS LASTPRICE ',
'Food.foodId AS fId',
'Food.restaurantsRestaurantId AS rID'
)
->from($this->entityClass,'Restaurant')
->innerJoin('Restaurant.foods','Food')
->where('Food.foodLastPrice IS NOT NULL')
->groupBy('Restaurant.restaurantId')
->getDQL();
$restaurantList = $qb
->select('Restaurants.restaurantName, Restaurants.restaurantId , j.LASTPRICE')
->from($this->entityClass,'Restaurants')
->leftJoin($getMaxPercentage,'j','WITH','Restaurants.restaurantId = j.rID')
->getQuery()->execute();
dd($restaurantList);
I give an error :
SELECT Restaurants.restaurantName,': Error: Class 'SELECT' is not defined.
I've already known I could set sub queries in main query, Although in this case I does not want to use sub query in Where expression. Any suggestion for using select in LeftJoin in doctrine?
EDITED : I've tried to use DQL in my query:
$query = $this->_em->createQuery(
'
SELECT Restaurants.restaurantName , Restaurants.restaurantId
FROM App\\Restaurant AS Restaurants
LEFT JOIN (
SELECT f.foodId AS fid,
f.restaurantsRestaurantId AS rid,
Max(f.foodLastPrice) AS LASTPRICE
FROM App\\Food AS f
LEFT JOIN App\\Restaurant AS r
WITH r.restaurantId = f.restaurantsRestaurantId
GROUP BY r.restaurantId) AS J
ON Restaurants.restaurantId = j.rid
');
But I gave an another error :
[Semantical Error] Error: Class '(' is not defined.
Is it possible to use select in left join in Doctrine?
EDITED 2 : I read a similar question and I've decided to write in another way :
$qb = $this->_em->createQueryBuilder();
$qb2 = $this->_em->createQueryBuilder();
$subSelect = $qb2
->select(
array(
'Food.foodLastPrice AS LASTPRICE ',
'Food.foodId AS fId',
'Food.restaurantsRestaurantId AS rId')
)
->from($this->entityClass,'Restaurant')
->innerJoin('Restaurant.foods','Food')
->where('Food.foodLastPrice IS NOT NULL')
->groupBy('Restaurant.restaurantId')
->getQuery()->getSQL();
$restaurantList =
$qb->select(
'Restaurant1'
)
->from($this->entityClass, 'Restaurant1')
->leftJoin('Restaurant1',sprintf('(%s)',$subSelect),'internalQuery','Restaurant1.restaurantId = internalQuery.rId')
->getQuery()->getSQL();
dd($restaurantList);
Again, I got an error:
near 'Restaurant1 (SELECT': Error: Class 'Restaurant1' is not defined.
What you're trying to do is impossible :
https://github.com/doctrine/doctrine2/issues/3542 (november 2013, but doctrine concept didn't change since and doctrinebot closed this on 7 Dec 2015)
DQL is about querying objects. Supporting subselects in the FROM
clause means that the DQL parser is not able to build the result set
mapping anymore (as the fields returned by the subquery may not match
the object anymore). This is why it cannot be supported (supporting it
only for the case you run the query without the hydration is a no-go
IMO as it would mean that the query parsing needs to be dependant of
the execution mode).
In your case, the best solution is probably to run a SQL query instead
(as you are getting a scalar, you don't need the ORM hydration anyway)
You can find workarounds like raw sql, or rethinking your query.

Symfony Doctrine Group By Query

I have below sql query running fine,
SELECT completed_by, count(*) AS Total
FROM tasks
WHERE completed_by is not null AND status = 1
GROUP BY completed_by
;
Em am doing it with doctrine query builder, but not working returning an error.
$parameters = array(
'status' => 1,
);
$qb = $repository->createQueryBuilder('log');
$query = $qb
->select(' log.completedBy, COUNT(log) AS Total')
->where('log.Status = :status')
->groupBy('log.completedBy')
->setParameters($parameters)
->getQuery();
and getting below error;
[Semantical Error] line 0, col 21 near 'completedBy,': Error: Invalid
PathExpression. Must be a StateFieldPathExpression.
I know this answer can be late, but I struggled with the exact same problem, and did not find any answer on the internet, and I believe a lot of people will struggle in this same issue.
I'm assuming your "completedBy" refers to another entity.
So, inside your repository, you can write:
$query = $this->createQueryBuilder("log")
->select("completer.id, count(completer)")
->join("log.completedBy", "completer")
->where('log.Status = :status')
->groupBy("completer")
->setParameters($parameters)
->getQuery();
This will compile to something like:
SELECT completer.id, count(completer) FROM "YOUR LOG CLASS" log INNER JOIN log.completedBy completer WHERE log.Status=:status GROUP BY completer
Now, You can do another query to get those 'completers', by their ids.
This is wrong: COUNT(log) AS Total. It should be something like COUNT(log.log) AS Total.
When you want to select a column who is a fk for another table (entity), use the IDENTITY function instead of the column name only.
Example: In your case
$parameters = array(
'status' => 1,
);
$qb = $repository->createQueryBuilder('log');
$query = $qb
->select('IDENTITY(log.completedBy), COUNT(log.something) AS Total')
->where('log.Status = :status')
->groupBy('log.completedBy')
->setParameters($parameters)
->getQuery();

How to select fields using doctrine 2 query builder

I have the following query I'm executing in Symfony2 Repository. The query looks like
$q = $this
->createQueryBuilder('m')
->select(array('m.reciever','m.created','m.id','m.subject'))
->where('m.reciever = ?1')
->orderBy('m.id','DESC')
->setMaxResults( '?2' )
->setFirstResult( '?3' )
->setParameter(1,$id)
->setParameter(2,$itemsPerPage)
->setParameter(3,$offset)
->getQuery();
Where reciever, created, id, and subject are fields part of my message entity. I do not need to specify which entity I am selecting from. The error I keep getting is such...
[Semantical Error] line 0, col 12 near 'reciever, m.created,': Error: Invalid PathExpression. Must be a StateFieldPathExpression.
I'm not sure what a state field path expression is or what the syntax might be. It seems like everything should be right.
When you use the select() method, you override the default one which is in $this->createQueryBuilder('m') . That's why you lost the m alias. To avoide this, use an addSelect() or specify the alias in the from() method:
->from('Bundle:Entity', 'ALIAS')
Do you have something like this:=?
$q = $this
->createQueryBuilder()
->select('m.reciever, m.created ,m.id , m.subject')
->from('/Acme/Entity/DemoEntity', 'm')
->where('m.reciever = ?1')
->orderBy('m.id','DESC')
->setMaxResults( '?2' )
->setFirstResult( '?3' )
->setParameter(1,$id)
->setParameter(2,$itemsPerPage)
->setParameter(3,$offset)
->getQuery();
Im not sure but I think you use the array syntax only if you have multiple tables to join together: array('m.reciever, m.created', 'p.user, p.id').
i hope this will help u..
$em = $this->getDoctrine()->getManager();
$q = $em->createQueryBuilder()
->select('m.reciever,m.created,m.id,m.subject')
->from('bundle:entity','m')
->where('m.reciever = ?1')
->orderBy('m.id','DESC')
->setMaxResults( '?2' )
->setFirstResult( '?3' )
->setParameter(1,$id)
->setParameter(2,$itemsPerPage)
->setParameter(3,$offset)
->getQuery();

How would I do MySQL count(*) in Doctrine2?

I have the following Doctrine2 query:
$qb = $em->createQueryBuilder()
->select('t.tag_text, COUNT(*) as num_tags')
->from('CompanyWebsiteBundle:Tag2Post', 't2p')
->innerJoin('t2p.tags', 't')
->groupBy('t.tag_text')
;
$tags = $qb->getQuery()->getResult();
When run I get the following error:
[Semantical Error] line 0, col 21 near '*) as num_tags': Error: '*' is not defined.
How would I do MySQL count(*) in Doctrine2?
You should be able to do it just like this (building the query as a string):
$query = $em->createQuery('SELECT COUNT(u.id) FROM Entities\User u');
$count = $query->getSingleScalarResult();
You're trying to do it in DQL not "in Doctrine 2".
You need to specify which field (note, I don't use the term column) you want to count, this is because you are using an ORM, and need to think in OOP way.
$qb = $em->createQueryBuilder()
->select('t.tag_text, COUNT(t.tag_text) as num_tags')
->from('CompanyWebsiteBundle:Tag2Post', 't2p')
->innerJoin('t2p.tags', 't')
->groupBy('t.tag_text')
;
$tags = $qb->getQuery()->getResult();
However, if you require performance, you may want to use a NativeQuery since your result is a simple scalar not an object.
As $query->getSingleScalarResult() expects at least one result hence throws a no result exception if there are not result found so use try catch block
try{
$query->getSingleScalarResult();
}
catch(\Doctrine\ORM\NoResultException $e) {
/*Your stuffs..*/
}

Categories