doctrine not exists subquery - php

I have in a repository this code:
public function getNotAssignedBy($speciality, $diploma)
{
$qb = $this->createQueryBuilder('j')
->select('DISTINCT(j.id) id', 'j.firstName', 'j.lastName', 'j.dateBirth', 'j.sex')
->leftJoin('j.qualifications', 'q')
;
if ($speciality) {
$qb->andWhere('q.speciality = :speciality_id')->setParameter('speciality_id', $speciality);
}
if ($diploma) {
$qb->andWhere('q.diploma = :diploma_id')->setParameter('diploma_id', $diploma);
}
$result = $qb->getQuery()->getResult();
return $result;
}
How can I get only rows where id not exists in another entity ??
Any help. Thanks

You can achieve it with something like this:
....
// construct a subselect joined with an entity that have a relation with the first table as example user
$sub = $this->createQueryBuilder();
$sub->select("t");
$sub->from("AnotherEntity","t");
$sub->andWhere('t.user = j.id');
// Your query builder:
$qb->andWhere($qb->expr()->not($qb->expr()->exists($sub->getDQL())));
Hope this help

Since I can't comment, so I will post a fixed version of #Matteo's solution
The correct way to use createQueryBuilder in this case is by using EntityManager. See my comment in the code below.
$sub = $this->_em->createQueryBuilder(); // _em stands for entity manager here. While $qb may use repositories createQueryBuilder() which requires alias
$sub->select("t");
$sub->from("AnotherEntity","t");
$sub->andWhere('t.user = j.id');
// Your query builder:
$qb->andWhere($qb->expr()->not($qb->expr()->exists($sub->getDQL())));

Related

show entity in second level of array in symfony

I don't know the exact term for showing the entity in second level of array.
I have entity Doctor. see my list in my image
If you can see the entity Person under the Doctor list. It display the Person entity like firstName and lastName. How can I show the same in facilityPackageDoctors? I expect it shows the package name and the facility, and what it displays now is not the list of facilityPackageDoctors. Here is my query
public function getFacilityPackageDoctors($facilityId){
$query = $this->createQueryBuilder('d')
->leftJoin('d.facilityPackageDoctors', 'fpd')
->leftJoin('fpd.facilityPackage', 'fp')
->where('fp.facility = :parameter')
->setParameter('parameter', $facilityId)
->getQuery();
return $query->getResult();
}
Do I have something to setup on this? sorry for the term I used.
thanks to ccKep. I found the solution by adding addSelect()
public function getFacilityPackageDoctors($facilityId){
$query = $this->createQueryBuilder('d')
->leftJoin('d.facilityPackageDoctors', 'fpd')
->leftJoin('fpd.facilityPackage', 'fp')
->addSelect('fpd')
->where('fp.facility = :facilityId')
->setParameter('facilityId', $facilityId)
->getQuery();
return $query->getResult();
}
Try with something like that
public function getFacilityPackageDoctors($facilityId){
$query = $this->createQueryBuilder('d')
->leftJoin('d.facilityPackageDoctors', 'fpd')
->leftJoin('fpd.facilityPackage', 'fp')
->addSelect('fp as facility')
->where('fp.facility = :parameter')
->setParameter('parameter', $facilityId)
->getQuery();
return $query->getResult();
}

Doctrine 2 simple "bigger than" criteria

In PDO / SQL i have a simple query with "bigger than":
DELETE * FROM tablexyz WHERE access > :old
Whats the equivalent in Doctrine 2 ORM?
I have already written a little code:
$criteria = ['access'=>$old];
$dataRepo = $entityManager->getRepository('tablexyz')->findBy($criteria)->delete();
My problem is, i want to use the bigger than operator in Doctrine 2 ORM but i don't want to make a function or class for that. Does somebody know a better or shorter solution for that?
You can use either a query builder og just do a direct DQL (or SQL) query for it.
$qb = $entityManager->createQueryBuilder();
$qb->select('e')
->from('Entityxyz', 'e')
->where('e.access > :old')
->setParameter('old', $old);
$entities = $qb->getQuery()->getResult();
or
$query = 'SELECT e FROM AppBundle\Entity\Entityxyz WHERE e.access > :old';
$entities = $entityManager->createQuery($query)
->setParameter('old', $old)
->getResult();`
I'd suggest you do create a repository method for it though, it's the correct place to have it. Using the query builder inside the repository is also simpler as it knows which entity you're referencing (and can skip calling select and from)
class EntityxyzRepository extends EntityRepository
{
public function getNewerThan($newerThan)
{
$qb = $this->createQueryBuilder('e');
$qb->where('e.access > :newerThan')
->setParameter('newerThan', $newerThan);
return $qb->getQuery()->getResult();
}
}

QueryBuilder/Doctrine Select join groupby

So recently I have been thinking and can't find a solution yet to this problem since my lack of development with doctrine2 and symfony query builder.
I have 2 tables:
Goals: id,user_id,target_value...
Savings: id,goal_id,amount
And I need to make a select from goals (all the informations in my table are from the goals table, except that I need to make a SUM(amount) from the savings table on each goal, so I can show the user how much did he saved for his goal)
This is the MySQL query:
select
admin_goals.created,
admin_goals.description,
admin_goals.goal_date,
admin_goals.value,
admin_goals.budget_categ,
sum(admin_savings.value)
from admin_goals
inner join admin_savings on admin_savings.goal_id=admin_goals.id
where admin_goals.user_id=1
group by admin_goals.id
It returns what I want but I have no idea how to implement it with doctrine or query builder, can you please show me an example in both ways?
I highly appreciate it !
I am going to assume you need this fields only and not your AdminGoals entity. On your AdminGoalsRepository you can do something like this:
public function getGoalsByUser(User $user)
{
$qb = $this->createQueryBuilder('goal');
$qb->select('SUM(savings.value) AS savings_value')
->addSelect('goal.created')
->addSelect('goal.description')
->addSelect('goal.goalDate')
->addSelect('goal.value')
->addSelect('goal.budgetCat') //is this an entity? it will be just an ID
->join('goal.adminSavings', 'savings', Join::WITH))
->where($qb->expr()->eq('goal.user', ':user'))
->groupBy('goal.id')
->setParameter('user', $user);
return $qb->getQuery()->getScalarResult();
}
Keep in mind that the return object will be an array of rows, each row is an associated array with keys like the mappings above.
Edit
After updating the question, I am going to change my suggested function but going to leave the above example if other people would like to see the difference.
First things first, since this is a unidirectional ManyToOne between AdminSavings and AdminGoals, the custom query should be in AdminSavingsRepository (not like above). Also, since you want an aggregated field this will "break" some of your data fetching. Try to stay as much OOP when you are not just rendering templates.
public function getSavingsByUser(User $user)
{
$qb = $this->createQueryBuilder('savings');
//now we can use the expr() function
$qb->select('SUM(savings.value) AS savings_value')
->addSelect('goal.created')
->addSelect('goal.description')
->addSelect('goal.goalDate')
->addSelect('goal.value')
->addSelect('goal.budgetCat') //this will be just an ID
->join('savings.goal', 'goal', Join::WITH))
->where($qb->expr()->eq('goal.user', ':user'))
->groupBy('goal.id')
->setParameter('user', $user);
return $qb->getQuery()->getScalarResult();
}
Bonus
public function FooAction($args)
{
$em = $this->getDoctrine()->getManager();
$user = $this->getUser();
//check if user is User etc depends on your config
...
$savings = $em->getRepository('AcmeBundle:AdminSavings')->getSavingsByUser($user);
foreach($savings as $row) {
$savings = $row['savings_value'];
$goalId = $row['id'];
$goalCreated = $row['created'];
[...]
}
[...]
}
If you use createQuery(), then you can do something like this:
$dqlStr = <<<"DSQL"
select
admin_goals.created,
admin_goals.description,
admin_goals.goal_date,
admin_goals.value,
admin_goals.budget_categ,
sum(admin_savings.value)
from admin_goals
inner join admin_savings on admin_savings.goal_id=admin_goals.id
where admin_goals.user_id=1
group by admin_goals.id
DSQL;
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery($dqlStr);
$query->getResult();
On the other hand, if you would like to use createQueryBuilder(), you can check this link: http://inchoo.net/dev-talk/symfony2-dbal-querybuilder/

How to print single value of entity without dumping the whole object?

I want to get one single value from entity.Can anyone help me here.
Here is my code.Please let me know what is missing here.
$query = $em->createQuery("SELECT e FROM AdminBundle:MailTemplates e WHERE e.keyword = '" .$keywordVal."'");
$query->execute();
$result = $query->getResult();
echo $result ->getId();
Here i want the 'id'.
This is noted in the documentation how you can do this.
So given you're code this will become:
$query = $em->createQuery("SELECT e.id FROM AdminBundle:MailTemplates e WHERE e.keyword = ?1");
$query->setParameter(1, $keywordVal);
$query->execute();
$result = $query->getResult(); // array of MailTemplates ids
Note: I also made use of setParameters instead of setting the value directly in the query.
In your controller:
$this->get('database_connection')->fetchColumn('select id from mail_templates where...');
That's much better for performance and much easier if you don't want to have a deal with query builder and other doctrine orm stuff.
Using the query builder you could do...
$queryBuilder = $em->createQueryBuilder('e');
$queryBuilder
->select('e.yourColumn')
// This will return just this column
// Alternatively you could omit any select to return the whole object
// that you could then use like $object->getYourColumn() if you so chose
->where($queryBuilder->expr()->eq('e.keyword', ':keyword'))
->setParameter('keyword', $keyword)
;
return $queryBuilder
->getQuery()
->getResult();
try this on loading Entities instead of creating own queries
Loading the entity with the Repository.
$rep = $this->getDoctrine()->getManager()->getRepository("Bundlename:Entity");
//find one by keyword -> single entity
$entity = $rep->findOneBy(array('keyword' => $keyword));
//find all by keyword - Array of entities
$result = $rep->findBy(array('keyword' => $keyword));

Symfony2 Query Builder Not Returning Many To One Value

I have an entity that has a column "inventoryLcoation_id" that has a many to one relationship. For some reason when I use createQueryBuilder() it is not returning that value in my ajax call, but it returns everything else: id, name, etc etc.. This is not an issue with Symfony2, its an issue with my lack of knowledge :)
Here is my query builder code:
$qb = $this
->createQueryBuilder('p')
->select('p.id', 'p.name')
->where('p.inventoryLocation = :inventoryId')
->andWhere('p.account = :account_id')
->setParameter('inventoryId', $value)
->setParameter('account_id', $account_id)
->orderBy('p.id', 'DESC');
if($qb->getQuery()->getArrayResult()){
return $qb->getQuery()->getArrayResult();
}else{
return false;
}
What do I need to code to have it also include the value from the inventoryLocation table which is mapped to the column value "inventoryLocation_id"?
Thanks so much for your help in enlightening my understanding to the awesome world of Symfony2!
try a join:
$qb->join('p.inventoryLocation','i')
and in the select especify both entities
$qb->select('p','i')
it should look like this:
$qb = $this
->createQueryBuilder('p')
->select('p','i')
->join('p.inventoryLocation','i')
->where('p.inventoryLocation = :inventoryId') // or ->where('i = :inventoryId')
->andWhere('p.account = :account_id')
->setParameter('inventoryId', $value)
->setParameter('account_id', $account_id)
->orderBy('p.id', 'DESC');

Categories