I am building a query throw querybuilder objects, something like
$qb = $em->createQueryBuilder()
->select('n, t, ns1m')
->from('App\Entity\Nuclei','n')
->leftJoin('n.statistiche1M', 'ns1m', 'WITH', 'DATE_PART(\'year\', ns1m.dataora) = YEAR(CURRENT_DATE())')
->leftJoin('n.codicitag', 't')
->where('n.comune = :id_comune')
->setParameter('id_comune', $this->user->getComune()->getId());
This query return an array of entity objects "nucleo":
array:3 [▼
0 => App\Entity\Nuclei { ... }
1 => App\Entity\Nuclei { ... }
2 => App\Entity\Nuclei { ... }
I want to add another column to select
->addSelect('SUM(ns1m.totale_peso_conferimenti_indifferenziata) AS total_test')
but now the result is:
array:2 [▼
0 => array:2 [▼
0 => App\Entity\Nuclei {#1671 ▶}
"total_test" => 1520
]
1 => array:2 [▶]
]
n.codicitag is a onetomany relations and is a collections of other objects
how can to handle this? Made many tests without success
What is your requested result? Result seems fine. You get sum for every Nuclei object.
If you need total sum without changing result structure, create extra query:
$qb = $em->createQueryBuilder()
->select('SUM(ns1m.totale_peso_conferimenti_indifferenziata) AS total_test')
->from('App\Entity\Statistiche1M','s1m')
->where('DATE_PART(\'year\', ns1m.dataora) = YEAR(CURRENT_DATE())');
This query return total sum filtered by current year.
You can try:
$qb = $em->createQueryBuilder()
->select('n, t, ns1m', 'SUM(ns1m.totale_peso_conferimenti_indifferenziata) AS total_test')
->from('App\Entity\Nuclei','n')
->leftJoin('n.statistiche1M', 'ns1m', 'WITH', 'DATE_PART(\'year\', ns1m.dataora) = YEAR(CURRENT_DATE())')
->leftJoin('n.codicitag', 't')
->where('n.comune = :id_comune')
->setParameter('id_comune', $this->user->getComune()->getId());
Because addSelect() create new array.
Related
I have a ManyToOne relation between two entities ArticleLine and Artcile:
<?php
//ArticleLine.php
ManyToOne(targetEntity="Gain\Bundle\ArticleBundle\Entity\Article")
I'm trying to get the list of Ids based on some where conditions..
This my doctrine query dql:
SELECT tl.id FROM AppBundle\Entity\ArticleLine tl INNER JOIN tl.turnover t INNER JOIN tl.article a WHERE t.supplier = :supplier AND t.year = :year AND tl.significant = false ORDER BY tl.id asc
After calling $qb->getQuery()->getResult() I'm getting this result of arrays...
array:138 [
0 => array:1 [
"id" => 64624
]
1 => array:1 [
"id" => 64630
]
2 => array:1 [
"id" => 64631
]
3 => array:1 [
"id" => 64632
]
4 => array:1 [
"id" => 64633
]
5 => array:1 [
"id" => 64637
]
6 => array:1 [
"id" => 64638
Any idea how I can transform my result to a one dimensional array or playing on hydration mode to get something like this
[64624, 64630, 64631, 64633 ... ]
or
[0 => 64624, 1 => 64630, 2 => 64631 ...]
You can transform your result with an array_map function:
$result = $qb->getQuery()->getResult()
$result = array_map('current', $result);
You can also use array_column fucntion:
$result = array_column($result, "id")
If a solution exists with an hydration mode. I would like to know :)
I have a problem with GroupBy.
I have entity with categories and entity with products. I want to get all the products grouped by category(id).
public function getAll()
{
$qb = $this->createQueryBuilder('p');
$qb->leftJoin('p.categories', 'category');
$qb->where('p.enabled = true');
$qb->andWhere('p.visible = true');
$qb->andWhere('p.quantity >= 1');
$qb->groupBy('category.id');
return $qb->getQuery()->getResult();
}
But this returns just few records(I think 1 from each category).
How can I get all products grouped in categories?
Thanks
So if you have something like this:
Category(id, name) 1-N Products (id, name, enabled, visible, quantity, category_id), and:
categories:
id name
1 category1
2 category2
products:
id name enabled visible quantity category_id
1 prod1 1 1 1 1
2 prod2 1 1 2 1
3 prod3 1 1 3 1
4 prod4 1 1 1 2
5 prod5 1 1 2 2
Then I think you should start from CategoryRepository, and:
public function getAll()
{
$qb = $this->createQueryBuilder('c');
$qb
->select('c.name')
->addSelect("(SELECT GROUP_CONCAT(p.name) FROM AppBundle:Product p WHERE p.category = c.id AND p.enabled = :enabled AND p.visible = :visible AND p.quantity >= :number) AS prods")
->setParameter('enabled', true)
->setParameter('visible', true)
->setParameter('number', 1)
;
return $qb->getQuery()->getResult();
}
The results will look like:
array:2 [▼
0 => array:2 [▼
"name" => "category1"
"prods" => "prod1,prod2,prod3"
]
1 => array:2 [▼
"name" => "category2"
"prods" => "prod4,prod5"
]
]
Also, you'll need to install beberlei's DoctrineExtensions to let doctrine know about GROUP_CONCAT function
I'm trying to update a certain number of rows of my entity "Vehicule". I have no idea how could it work.
I'm actually trying to modify only two rows where direction= 5.This is the function I used in order to update.
public function ValidAction(\OC\UserBundle\Entity\User $direction) {
$qb = $this->getDoctrine()
->getRepository('CarPfeBundle:Vehicule')
->createQueryBuilder('v');
$q = $qb->update ('CarPfeBundle:vehicule v')
->set('v.direction', '?1')
->where('v.direction = ?2')
->setParameter(1, $direction)
->setParameter(2, 5)
->getQuery();
$p = $q->execute();
return $this->redirect($this->generateUrl('demandeveh_afficher'));
}
But the above code update all rows of my database. I need to update only two rows. Any help please?
Try to do this ;
public function ValidAction(\OC\UserBundle\Entity\User $direction) {
$qb = $this->getDoctrine()
->getRepository('CarPfeBundle:Vehicule')
->createQueryBuilder('v');
// $ids an array that contains all ids with your condition
$ids = $qb->select('v.id')
->where('v.direction = :direction')
->setParameter(
array(
'direction' => $direction
)
)
->getQuery()
->getResult();
$id1 = $ids[array_rand($ids)];
$id2 = $ids[array_rand($ids)];
//To be sure that $id1 is different from id2
while ($id1 == $id2) {
$id2 = $ids[array_rand($ids)];
}
$q = $qb->update ('CarPfeBundle:vehicule v')
->set('v.direction', ':val1')
->where('v.direction = :val2')
->andWhere('v.id IN (:id1, :id2)')
->setParameter(
array(
'val1' => $direction ,
'val2' => 5 ,
'id1' => $id1,
'id2' => $id2,
)
)
->getQuery();
$p = $q->execute();
return $this->redirect($this->generateUrl('demandeveh_afficher'));
}
With the above code I hope you can update only two rows and randomly.
Good luck !
While a solution like Houssem Zitoun suggested may work, why not use a subquery?
If you get the (like I did, if not, just skip the middle SELECT)
Error: #1235 - This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
go with this answer and something like (doc): - untested
UPDATE CarPfeBundle:Vehicule v
SET v.direction = ?1
WHERE v.direction IN
(SELECT * FROM (
SELECT v.direction
FROM CarPfeBundle:Vehicule v2
WHERE v.direction = ?2 LIMIT 2
)) AS sq
I have the following tables in mysql with given relationships and same has been define in the symfony2. I want to achieve the following query which I wrote it down below. can some one help me how can I write it in querybuilder?
unitids(id,unitid,databaseid)
Mappaths(id,ref_unitid2(forigen key for unitids id) ,ref_unitid1 (forigen key for unitids id),nomal value)
traveltime(id,ref_map_path(forigen key for mappaths id), traveltime,noobjs,ondate)
my mysql query is like this :
SELECT t.ID,t.ondate, un.databaseid as source1,
un1.databaseid as desitnation, t.traveltime, t.noobjs
FROM test.traveltime t
left join test.mappaths p on t.ref_map_path = p.ID
left join test.unitids un on (p.ref_unitids1 = un.id )
left join test.unitids un1 on (p.ref_unitids2= un1.id)
where un.databaseid=50 and un1.databaseid =1 limit 1;
which give me each one row of source and destination of and objects etc like this :
in symfony2 when i run this query
$query = $em->createQueryBuilder();
$results = $query->select('un.databaseid,un1.databaseid')
->from('ApiMapBundle:Traveltime', 't')
->leftJoin('t.refMapPath', 'p')
->leftJoin('p.refUnitids2', 'un')
->leftJoin('p.refUnitids1', 'un1')
->where('un.databaseid = :bdatabaseid1')
->setParameter('bdatabaseid1', 2)
->andwhere('un1.databaseid = :bdatabaseid2')
->setParameter('bdatabaseid2',1)
//->setMaxResults(1)
->getQuery()
->getResult();
it give me output like
Array ( [0] => Array ( [databaseid] => 1 ) [1] => Array ( [databaseid] => 1 ))
but instead it should give me
Array ( [0] => Array ( [databaseid] => 1 ) [1] => Array ( [databaseid] => 2 ))
How can i achieved this above output?????
Assumed that you are writing code in Repository and you also defined relations in your Entities
$em = $this->getEntityManager();
$query = $em->getRepository('BUNDLE:traveltime')->createQueryBuilder('t');
$query->select('t.Id,..')
->leftJoin('t.ref_map_path','p')
->leftJoin('p.ref_unitids1','un')
->leftJoin('p.ref_unitids2','un1')
->where('un.databaseid = :bdatabaseid')
->setParameter('bdatabaseid',1)
->orWhere('un1.databaseid = :bdatabaseid1')
->setParameter('bdatabaseid1',2);
I have around 60 entities, all referring (manyToOne or oneToOne) to a "uber entity" called "project".
I'm developing a dashboard, so once selected the project I have to get all "children" entities referred to the project.
So I have:
class Entity1{
...
/**
* #ORM\OneToOne(targetEntity="Project")
*/
protected $project;
...
}
or
class Entity2{
...
/**
* #ORM\ManyToOne(targetEntity="Project")
*/
protected $project;
...
}
Of course I could do:
$entitiesToCheckStatusFor = ['Entity1', 'Entity2', ..., 'Entity60', ];
$entitiesStatus = [];
foreach ($entitiesToCheckStatusFor as $entityToCheckStatusFor){
$entitiesStatus[$entityToCheckStatusFor] = $em->getRepository('AppBundle:'.$entityToCheckStatusFor)->findByProject($project);
}
But it means 60 queries. It's far from elegant.
I basically need a JOIN between unrelated entities so that I can make a single query.
I tried something like:
$query = $em->createQuery('SELECT ai, pn, pb, pd p FROM AppBundle:Project p '
. 'LEFT OUTER JOIN AppBundle:ProjectNotification pn WITH p.id = pn.project '
. 'LEFT OUTER JOIN AppBundle:ProjectDetail pd WITH p.id = pd.project '
. 'LEFT OUTER JOIN AppBundle:ProjectBenefit pb WITH p.id = pb.project '
. 'LEFT OUTER JOIN AppBundle:ActionItem ai WITH p.id = ai.project '
. 'WHERE p.id = :projectid'
)->setParameter('projectid', $project->getId());
$mixedStuff = $query->getResult();
but it returns a lot of nulls when there are no entities:
array:20 [▼
0 => Project {#8285 ▶}
1 => null
2 => ProjectDetail {#3028 ▶}
3 => null
4 => ActionItem {#2978 ▶}
5 => null
6 => null
7 => ActionItem {#3191 ▶}
8 => null
9 => null
10 => ActionItem {#3200 ▶}
11 => null
12 => null
13 => ActionItem {#3205 ▶}
14 => null
15 => null
16 => ActionItem {#3210 ▶}
17 => null
18 => null
19 => ActionItem {#3214 ▶}
]
I could live with the nulls, but I was hoping to get rid of them. Besides in this case I was expecting to get 2 nulls (one for ProjectNotification and another for ProjectBenefit, while I have a lot. Why?
Any other advice?
Thank you!
I don't see the need of use LEFT OUTER JOIN. If relations are properly configured, especially in project entity you can make a simple JOIN and get not nulls.
$query = $em->createQuery('SELECT p, pn, pd,pb, pa '
. 'FROM AppBundle:Project p '
. 'JOIN p.notifications pn '
. 'JOIN p.details pd '
. 'JOIN p.benefits pb '
. 'JOIN p.actions pa '
. 'WHERE p.id = :id ')
->setParameter('id', $project->getId());