How to combine dql queries - dql

I have two DQL queries
$dql = "SELECT i FROM Edufaction\Bundle\EdufactionBundle\Entity\Institute i JOIN i.instsummary s where s.instaffiliation IN ($affiliation1)";
$dql = "SELECT i FROM Edufaction\Bundle\EdufactionBundle\Entity\Institute i where i.institutefeerange IN ($feerange)";
how do I combine these two queries into single query?

You could try something like this using the AND operator
$dql = "SELECT i FROM Edufaction\Bundle\EdufactionBundle\Entity\Institute i JOIN i.instsummary s where s.instaffiliation IN ($affiliation1) AND i.institutefeerange IN ($feerange)";

Related

Doctrine Native query inside query builder join

I am working on a query on Doctrine 2 (with Symfony 2.8)
I have this query giving me relevant info:
$qb = $this->createQueryBuilder('ea');
$qb->join('ea.entity_b', 'eb')
->join('ea.entity_c', 'ec')
->join('ec.entity_d', 'ed')
->join('MainBundle:Entity_E', 'ee','WITH', 'ee.column1 = ea.id')
->join('MainBundle:Entity_F', 'ef', 'WITH', 'ea.column1 = ef.id');
Now, I need to add extra info to that query, but it comes from a native SQL, something like this:
SELECT * FROM DS ORDER BY id DESC LIMIT 1
And make sure that the id of the result from the native query is equal to ef.id
I hope I made any sense.
Thanks
Do you know DQL ?
Similar to SQL but adapted for Doctrine.
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/dql-doctrine-query-language.html
You can then do queries like :
<?php
$query = $em->createQuery("SELECT u FROM User u JOIN u.address a WHERE a.city = 'Berlin'");
$users = $query->getResult();

Complex AX Query

i want to rebuild this SQL Query as AX Query.
I tried it in several ways, but I don't get it.
I am not completely new to AX queries, but I only have experience with some simple queries not with such complex SQL queries.
SELECT * FROM ( SELECT DH.[RECID] AS RECID_DIMENSIONHIERARCHY
,DH.[NAME] AS NAME__DIMENSIONHIERARCHY
,DH.[DESCRIPTION] AS DESC__DIMENSIONHIERARCHY
,DH.[PARTITION] AS PARTITION_DIMENSIONHIERARCHY
,DL.[DIMENSIONATTRIBUTE] AS RECID_DIMENSIONATTRIBUTE
,DA.[NAME] AS NAME_DIMENSIONATTRIBUTE
,DN.[RECID] AS RECID_DIMENSIONCONSTRAINTNODE
,DNC.[RECID] AS RECID_DIMENSIONCONSTRAINTNODECRITERIA
,DNC.[RANGETO] AS #Owner
,DNCR.[WILDCARDSTRING] AS #Agreement
FROM (SELECT * FROM [dbo].[DIMENSIONHIERARCHY]
WHERE [STRUCTURETYPE] = 1 AND [NAME] LIKE 'AG-OW%'
) AS DH
INNER JOIN [dbo].[DIMENSIONHIERARCHYLEVEL] AS DL
ON DH.[RECID] = DL.[DIMENSIONHIERARCHY]
AND DH.[PARTITION] = DL.[PARTITION]
INNER JOIN [dbo].[DIMENSIONATTRIBUTE] AS DA
ON DL.[DIMENSIONATTRIBUTE] = DA.[RECID]
AND DL.[PARTITION] = DA.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODE] AS DN
ON DL.[RECID] = DN.[DIMENSIONHIERARCHYLEVEL]
AND DL.[PARTITION] = DN.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODECRITERIA] AS DNC
ON DN.[RECID] = DNC.[DIMENSIONCONSTRAINTNODE]
AND DN.[PARTITION] = DNC.[PARTITION]
INNER JOIN [dbo].[DIMENSIONCONSTRAINTNODECRITERIA] AS DNCR
ON DN.[PARENTCONSTRAINTNODE] = DNCR.[DIMENSIONCONSTRAINTNODE]
AND DN.[PARTITION] = DNCR.[PARTITION]
) AS Sub
You need to break down your query and implement it in small chunks. Then combine all of it to get the desired result.
There are two ways to create query in X++.
Create query using select statement for example:
Select * from HcmWorker join * from DirPerson
where DirPerson.RecId == HcmWorker.Person
See this link : Select statement syntax
Create query with AOT structure. You might want to have a look at the following link:
Create query in AOT by using X++

Doctrine left join on unrelated entity

Is there any way to do this. I'm getting more and more confused trying different things.
I have an entity conferences that can have a place.
Places are in a many to one relationship with city.
In my query I'm trying to retrieve the city info but can't seem to retrieve it in the same place result.
This is the query used:
$qbt = $this->_em->createQueryBuilder();
$qbt
->select('conference', 'diffusion', 'speaker', 'placediff', 'confcity')
->from('AppBundle:Conference', 'conference')
->leftJoin('conference.diffusion', 'diffusion')
->leftJoin('conference.speaker','speaker')
->leftJoin('conference.place','placediff')
->leftJoin('AppBundle:City', 'confcity', 'WITH', 'confcity.id = placediff.city');
return $qbt
->getQuery()
->setHint(\Doctrine\ORM\Query::HINT_INCLUDE_META_COLUMNS, true)
->useQueryCache(true)
->useResultCache(true, 3600)
->getArrayResult();
This is what is returns, currently have only one conference.
Would love to have the second array inside place though.
Any ideas on how to accomplish this? Much obliged ~
(UPDATE) In the meantime I switched to raw sql query but really looking for a way to do this using dql
public function rawConf()
{
$conn = $this->getEntityManager()->getConnection();
$sql = 'SELECT
c0_.id AS id,
c0_.startAt AS startat,
c0_.comment AS comment,
d1_.id AS diffusion_id,
d1_.hour AS diffusion_hour,
s2_.id AS speaker_id,
c0_.place_id AS place_id,
c0_.sponsor_id AS sponsor_id,
c0_.tour_id AS tour_id_8,
d1_.movie_id AS diffusion_movie_id,
s2_.contact_id AS speaker_contact_id,
c6_.name AS ville_name,
c6_.postal AS ville_post,
c6_.department as ville_depart
FROM
conference c0_
LEFT JOIN conference_diffusion c3_ ON c0_.id = c3_.conference_id
LEFT JOIN diffusion d1_ ON d1_.id = c3_.diffusion_id
LEFT JOIN conference_speaker c4_ ON c0_.id = c4_.conference_id
LEFT JOIN speaker s2_ ON s2_.id = c4_.speaker_id
LEFT JOIN place p5_ ON c0_.place_id = p5_.id
LEFT JOIN city c6_ ON (c6_.id = p5_.city_id)';
$stmt = $conn->prepare($sql);
$stmt->execute();
return $stmt->fetchAll();
}
You should get "city" from "place" as "$city" is a property of Place entity. Try this simplified query to see it works:
$qbt = $this->_em->createQueryBuilder();
$qbt
->select('conference')
->addSelect('place')
->addSelect('city')
->from('AppBundle:Conference', 'conference')
->innerJoin('conference.place', 'place')
->innerJoin('place.city', 'city')
;
And if it works - you could easily add more joins if you need.

Doctrine query builder - nested queries, AS keyword, select functions

SELECT t1.field1 AS foo, (SELECT ABS(SUM(amount)) FROM table2 t2) FROM table1;
How can I convert this query into symfony 2 doctrine query builder?
$results = $this->getEntityManager()->createQueryBuilder()
->select(...)
//...
$results = $this->getEntityManager()->createQueryBuilder()
->select('t1.field1')
->addSelect('abs(sum(amount)) t2')
->from('BundleName:Entity', 't1)
->leftJoin('t1.field', 'another')
->getQuery()->getResult();
Maybe this works, I found a similar problem and a solution here:
Select Subquery with COUNT() in Doctrine DQL
Or if it not works, you can create two queries for the problem, and you use the first query's result in the second query.

Doctrine ManyToMany Query

I have a Product Entity which has a ManyToMany relationship with a Taxon Entity. I want to find all the products that belong to the intersection of all Taxons. For instance I want to find all products that belong to taxons with IDs 1 and 2.
Products
{1,2,3}
Taxons
{1,2,3,4,5}
ProductsToTaxons
{{p1,t1},{p1,t2}, {p2,t2}}
I want to retrieve the following set ONLY when querying products for taxons 1 and 2:
Product
{1}
which is from {{p1,t1}, {p1,t2}}
Okay, So here is the DQL that i tried... but it doesn't work?
SELECT p FROM SRCProductBundle:Product p
JOIN p.taxons t
WHERE t.id = 1 AND t.id = 2
(P.S. I would also do this with QueryBuilder with as well)
EDIT
To clarify, here is the SQL that I would like to translate into DQL/QueryBuilder.
select p.id
from product p
where exists (select product_id
from product_to_taxon
where taxon_id = 1
and product_id = p.id)
and exists (select product_id
from product_to_taxon
where taxon_id = 4
and product_id = p.id);
You can use the MEMBER OF statement to achieve this although in my experience it hasn't produced very performant results with a ManyToMany relationship:
In DQL:
SELECT p FROM SRCProductBundle:Product p
WHERE 1 MEMBER OF p.taxons OR 2 MEMBER OF p.taxons
Or with Query builder
$this->createQueryBuilder('p')
->where(':taxon_ids MEMBER OF p.taxons')
->setParameter('taxon_ids', $taxonIdsArray)
->getQuery()
->getResult();
This will create SQL similar to the example provided although in my experience it still had a join in the EXISTS subqueries. Perhaps future versions of Doctrine can address this.
I think you want something like this:
$qb = $this
->createQueryBuilder('p')
->select('p.id')
;
$qb
->leftJoin('p.taxons', 'taxon1', Join::WITH, 'taxon1.id = :taxonId1')
->setParameter('taxonId1', 1)
->andWhere($qb->expr()->isNotNull('taxon1'))
->leftJoin('p.taxons', 'taxon2', Join::WITH, 'taxon2.id = :taxonId2')
->setParameter('taxonId2', 2)
->andWhere($qb->expr()->isNotNull('taxon2'))
;
Which is equivalent to the SQL:
SELECT p.id
FROM products p
LEFT JOIN taxons t1 ON (p.id = t1.product_id AND t1.id = 1)
LEFT JOIN taxons t2 ON (p.id = t2.product_id AND t2.id = 2)
WHERE t1.id IS NOT NULL
AND t2.id IS NOT NULL
;
Your DQL has wrong logic. You can't have a taxon with both id=1 and id=4. You could do it like this:
SELECT p FROM SRCProductBundle:Product p
JOIN p.taxons t
WHERE t.id = 1 OR t.id = 4
But I would prefer this way:
SELECT p FROM SRCProductBundle:Product p
JOIN p.taxons t
WHERE t.id IN (1, 4)
Using query builder that would look something like this, assuming you're in EntityRepository class:
$this->createQueryBuilder('p')
->join('p.taxons', 't')
->where('t.id IN :taxon_ids')
->setParameter('taxon_ids', $taxonIdsArray)
->getQuery()
->getResult();
For lack of a clean way to do this with DQL, and after a considerable amount of research, I resorted to doing this in Native SQL. Doctrine allows Native SQL via the EntityManager with createNativeQuery().
So in short, I utilized this ability and constructed the SQL query included in my question as a string and then passed it to the createNativeQuery() function.
This does appear to have some drawbacks as it appears I will be unable to use the KnpPaginatorBundle with it... So I might end up just filtering the results in PHP rather than SQL, which I'm hesitant to do as I think there are performance drawbacks.

Resources