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..*/
}
Related
I need to write some complex query builder expression. The sql looks like:
SELECT query,popularity,nb_words
FROM gemini_suggestion
WHERE query IN
(
SELECT * FROM
(
SELECT query
FROM gemini_suggestion
GROUP BY query
HAVING COUNT(query) > 1
) AS subquery
);
The code im stucked at is:
$queryBuilder = $em->createQueryBuilder();
$queryBuilder->select('a')
->from($this->entity['class'], 'a')
->where($queryBuilder->expr()->In('a.query', $subQuery->getDQL()));
$subQuery2 = $em->createQueryBuilder()
->select('b.query')
->from($this->entity['class'], 'b')
->groupBy('b.query')
->having('count(b.query)>1')
;
$subQuery = $em->createQueryBuilder();
$subQuery->select('a')
->from(...)
;
Any help would be nice!
You can try something like this. I'm assuming you have a namespace Entities where you have all your entities classes.
// Subquery to get the queries greater than 1
$subQueryBuilder = $this->entityManager->createQueryBuilder();
$subQueryBuilder->select('gemini_suggestion.query')
->from('Entities\gemini_suggestion', 'gemini_suggestion')
->groupBy('gemini_suggestion.query')
->having($subQueryBuilder->expr()->gt('COUNT(gemini_suggestion.query)', 1));
// Main query where you use the subquery to filter out the records you want
$queryBuilder = $this->entityManager->createQueryBuilder();
$queryBuilder->select('query, popularity, nb_words')
->from('Entities\gemini_suggestion', 'gemini_suggestion')
->where($queryBuilder->expr()->in('gemini_suggestion.query', $subQueryBuilder->getDQL()));
$result = $queryBuilder->getQuery()->getResult();
return $result;
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();
I try to use "distinct on" with doctrine but I get the following error:
Error: Expected known function, got 'on'
class Report extends EntityRepository
{
public function findForList() {
$queryBuilder = $this->createQueryBuilder('r');
$queryBuilder->select('distinct on (r.parentId)')
->orderBy('r.parentId')
->orderBy('r.date', 'DESC');
return $queryBuilder->getQuery()->getResult();
}
}
How could I implement the following query?
select distinct on (r.parent_id)
r.parent_id,
r.id,
r.name
from frontend.report r
order by r.parent_id, r.date desc;
Apparently it doesn't seem possible to do this with the query builder. I tried to rewrite my query in different ways:
select * from frontend.report r
where
r.id in (
select distinct
(select r3.id from frontend.report r3
where r3.parent_id = r.parent_id
order by r3.date desc limit 1) AS id
from frontend.report r2);
But doctrine doesn't support LIMIT:
public function findForList() {
$qb3 = $this->_em->createQueryBuilder();
$qb3->select('r3.id')
->from('MyBundle:frontend\report', 'r3')
->where('r3.parentId = r2.parentId')
->orderBy('r3.date', 'DESC')
//->setMaxResults(1)
;
$qb2 = $this->_em->createQueryBuilder();
$qb2->select('(' . $qb3->getDql() . ' LIMIT 1)')
->from('MyBundle:frontend\report', 'r2')
->distinct(); // groupBy('r2.parentId')
$queryBuilder = $this->createQueryBuilder('r');
$queryBuilder->where(
$queryBuilder->expr()->in('rlt.id', $qb2->getDql())
);
return $queryBuilder->getQuery()->getResult();
}
I think the only solution is to use native SQL queries.
This response is for someone that yet looking for the solution in similar cases.
If you need a sample "DISTINCT" you can use:
$queryBuinder->select('parentId')
->distinct('parentId');
but if you want a "DISTINCT ON" you should use Native SQL instead of Query Builder, check out the manual here: Doctrine Native SQL
Just remove the on word :
$queryBuilder->select('distinct r.parentId')
->orderBy('r.parentId')
->orderBy('r.date', 'DESC');
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();
As part of my website I'm trying to a create tagging (folksonomy) system using Symfony2 and Doctrine2.
I'm following the table and query examples in the document below to create my Doctrine Entities: http://dablog.ulcc.ac.uk/wp-content/uploads/2007/12/tagging_folksonomy.pdf
When I try to convert the MySQL queries (given in the document) to Doctrine Query Builder queries I get errors with the innerJoins. Example below:
MySQL query from the document:
SELECT tag_text
, COUNT(*) as num_tags
FROM Tag2Post t2p
INNER JOIN Tags t
ON t2p.tag_id = t.tag_id
GROUP BY tag_text;
My Doctrine Query Builder query:
$qb = $em->createQueryBuilder()
->select('t.tag_text, COUNT(*) as num_tags')
->from('CompanyWebsiteBundle:Tag2Post', 't2p')
->innerJoin('CompanyWebsiteBundle:Tags', 't', 'ON', 't2p.tag_id = t.id')
->groupBy('t.tag_text')
;
$tags = $qb->getQuery()->getResult();
Error message:
[2/2] QueryException: [Syntax Error] line 0, col 112: Error: Expected Doctrine\ORM\Query\Lexer::T_WITH, got 'ON'
[1/2] QueryException: SELECT t.tag_text, COUNT(*) as num_tags FROM CompanyWebsiteBundle:Tag2Post t2p INNER JOIN CompanyWebsiteBundle:Tag t ON t2p.tag_id = t.id GROUP BY t.tag_text
When I run the MySQL query directly on the database it works!
This should work. In DQL, the ON keyword is replaced by WITH.
$qb = $em->createQueryBuilder()
->select('t.tag_text, COUNT(*) as num_tags')
->from('CompanyWebsiteBundle:Tag2Post', 't2p')
->innerJoin('CompanyWebsiteBundle:Tags', 't', 'WITH', 't2p.tag_id = t.id')
->groupBy('t.tag_text')
;
$tags = $qb->getQuery()->getResult();
Also if you have properly configured entities, you should be able to leave out the , 'WITH', 't2p.tag_id = t.id' part as doctrine should automatically find the relations.
For example:
$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();