How I can create multiple join with DQL - symfony

How I can create multiple join with DQL , something like this in sql:
SELECT t,c,u FROM `user` AS t
LEFT JOIN (`contract` AS c, `car` AS u)
ON (t.id = c.`user_id` AND u.id = c.`unit_id` AND u.name = 'audi')
WHERE t.email = 'test#example.com';
Solve problem by another way, create sub-query:
$query = $this->createQueryBuilder('user')
->addSelect(
array('contract', 'car')
)
;
$query->leftJoin(
'user.contracts',
'contract',
Expr\Join::WITH,
'contract.id IN (
SELECT contract2.id
FROM DataBundle:User user2
INNER JOIN user2.contracts contract2
INNER JOIN contract2.car car2
WHERE user2.email = :email AND (
contract2.status = :status1 OR contract2.status = :status2
) AND car2.name = :name
)'
);
$query->leftJoin(
'contract.car',
'car'
);
$query->where('user.email = :email');
Maybe will be useful for someone.

See article for multiple join example :
DQL JOIN Syntax:
[[LEFT | INNER] JOIN <component_reference1>] [ON | WITH] <join_condition1> [INDEXBY] <map_condition1>,
[[LEFT | INNER] JOIN <component_reference2>] [ON | WITH] <join_condition2> [INDEXBY] <map_condition2>,
...
[[LEFT | INNER] JOIN <component_referenceN>] [ON | WITH] <join_conditionN> [INDEXBY] <map_conditionN>

You will end up with something like this:
SELECT user,contract,car
FROM user AS user
LEFT JOIN user.contract AS contract
LEFT JOIN contract.car AS car
WHERE user.email = 'test#example.com' AND car.name = 'audi';
Obviously you need to define your entities and set up the relations properly. I'd suggest following the example in the documentation and then working your way through a test case.
Please note that the use of abbreviations (t,c,u) for aliases has been declared a war crime by the United Nations and will be punished severally.

Related

QueryBuilder - Use Select in an innerJoin

can someone help me.
I need to change my sql query to a querybuilder. I don't know how to use select inside a innerJoin.
Here my sql query:
SELECT
user.id,
analytic_youtube_demographic.age_group,
analytic_youtube_demographic.percentage
FROM
user
INNER JOIN user_youtube ON user_youtube.id = user.id
INNER JOIN analytic ON analytic.id = user_youtube.analytic_id
INNER JOIN analytic_youtube_demographic ON analytic_youtube_demographic.analytic_id = analytic.id
INNER JOIN
(
SELECT analytic_youtube_demographic.id as id, MAX(analytic_youtube_demographic.percentage) max
from user
INNER JOIN user_youtube ON user_youtube.id = user.id
INNER JOIN analytic ON analytic.id = user_youtube.analytic_id
INNER JOIN analytic_youtube_demographic ON analytic_youtube_demographic.analytic_id = analytic.id
GROUP BY user.id
) AS T ON analytic_youtube_demographic.percentage = T.max
WHERE analytic_youtube_demographic.age_group IN ('18-24')
Thanks a lot for your help.

SQLITE unwanted behavior on group_concat in query

I have two tables like this:
Fiddle: click here
My query:
select
f.id,
'{{' || group_concat(f.key||','||ifnull(f.value,'NULL'), '},{')||'}}' as
key_value_pair_1,
'{{' || group_concat(r.key||','||ifnull(r.value,'NULL'), '},{')||'}}' as
key_value_pair_2
FROM items_functions as f
LEFT JOIN items_functions_2 as r ON f.id = r.id
GROUP BY f.id
But this results into a strange behavior. All results where shown multiple times as you can see when you run the above linked fiddle.
But what I want is a result like this:
id key_value_pair_1 key_value_pair_2
214808 {{16,662},{17,808},{33,1},{60,2}} {{16,662},{17,808},{33,1},{60,2}}
214809 {{16,902},{17,1103},{33,1},{60,2}} {{16,902},{17,1103},{33,1},{60,2}}
218965 {{19,808},{21,662},{33,1},{60,8}} {{19,808},{21,662},{33,1},{60,8}}
218966 {{19,1103}{21,902},{33,1},{60,8}} {{19,1103},{21,902},{33,1},{60,8}}
244574 {{16,999},{18,999},{54,174}} {{16,999},{18,999},{54,174}}
I guess my query has to be adjusted. :)
Would be awesome, if anyone is happen to have a solution on this.
Thanks in advance!
Best regards,
Andreas
I believe the following will do what you want :-
SELECT
p1.id, p1.kvp1, p2.kvp2
FROM
(
SELECT
id,
'{{' || group_concat(key||','||ifnull(value,'NULL'), '},{')||'}}'
AS kvp1
FROM items_functions GROUP BY id
)
AS p1
JOIN
(
SELECT
id,
'{{' || group_concat(key||','||ifnull(value,'NULL'), '},{')||'}}'
AS kvp2
FROM items_functions_2 GROUP BY id
)
AS p2
ON p1.id = p2.id
Which produces :-

DQL request from = to IN

I have an issue with the IN instruction for a field...maybe you can see better than me what's happening.
The issue is on the waves parameter.
I got this in my database it's a configuration field...and this field contain a json
{
"typeId":"10,57",
"codeVague":"ITM1702A,ITMTEST"
}
This request inside sql return results:
SELECT v.id,v.`vague_code`, v.`date_fin_ultime`,m.*
FROM Vague v
INNER JOIN Enquete e ON e.`vague_id` = v.`id`
INNER JOIN Mission m ON m.id = e.`mission_id`
INNER JOIN Contrat c ON c.id = m.`contrat_id`
INNER JOIN `User` u ON u.`enqueteur_id` = e.`enqueteur_id`
INNER JOIN `PointDeVente` p ON p.id = e.`pdv_id`
WHERE v.`vague_code` IN ('ITM1702A','ITMTEST')
AND type_id IN (10,57)
But when I try to do the same from my symfony controller...I got an empty result
$sql="SELECT v.id,v.codeVague, v.date_fin_ultime,c.distance,p.adresse1,p.code_postal,p.ville,m
FROM McInvestigatorBundle:Vague v
INNER JOIN McInvestigatorBundle:Enquete e WITH e.vague_id = v.id
INNER JOIN McInvestigatorBundle:Mission m WITH m.id = e.mission_id
INNER JOIN McInvestigatorBundle:Contrat c WITH c.id = m.contrat
INNER JOIN McInvestigatorBundle:User u WITH u.enqueteur_id = e.enqueteur_id
INNER JOIN McInvestigatorBundle:PointDeVente p WITH p.id = e.pdv_id
WHERE v.codeVague IN (:waves)
AND e.type_id IN (:type_id)
AND m.enqueteur_id=:enq_id
ORDER BY m.date_rea_prev ASC";
$results= $em->createQuery($sql)->setParameters([
'waves' => $waves,
'type_id' => $type_id,
'enq_id' => $enq_id,
])->getResult();
The strange thing is that I got no issue with type_id, it works fine.
But, the waves field it's not the same story....
In fact, it works only if I have only one value in the json
"codeVague":"ITM1702A" is working
"codeVague":"ITM1702A,ITMTEST" is not working.
I already tried those strings in $waves.
"ITM1702A,ITMTEST" and "'ITM1702A','ITMTEST'" and "'ITM1702A,ITMTEST'"
Thanks you for your help !
EDIT: Problem solved, thanks Veve.

Doctrine DQL with multiple joined tables

i have entities **target,citytarget,city,cityplace,place
citytarget & cityplace are pivot tables that connect t&c and c&p
i need the places for given city name and a target id
i tried the following DQL:
SELECT t,c,p FROM MulticatorBundle:Target t
join t.cities ct
join ct.cities c
join c.places cp
join cp.places p
where c.name like '%Stahmeln%'
But i receive:
result: The parent object of entity result with alias 'c' was not found. The parent alias is 'ct'.
i dont know any further....
a plain SQL could be:
select * from target
left join citytarget on citytarget.target_id = target.id
left join city on citytarget.city_id = city.id
left join cityplace on cityplace.city_id = city.id
left join place on cityplace.id = place.id
where target.id = 1
and city.name like \'%Stahmeln%\'
Adrian
You always need your parent entity in your select. In this case:
SELECT ct, c, cp, t, p
is needed
You need to do
SELECT t,ct, c, cp ,p FROM MulticatorBundle:Target t
join t.cities ct
join ct.cities c
join c.places cp
join cp.places p
where c.name like '%Stahmeln%'
Hope this help you

Limit the subquery results in DQL

I want to use LIMIT 1 clausule on the subquery in SELECT in DQL query...How can I do that?
"SELECT partial p.{productId, productName, count, price, utwTs},
(
SELECT pp.fileName
FROM AdminBundle:ProductPhoto pp
WHERE pp.productId = p.productId
// LIMIT 1 <--- here
) AS photo_name,
u.avatarName
FROM AdminBundle\Entity\Product p
LEFT JOIN AdminBundle\Entity\Users u WITH u.id = p.userId
LEFT JOIN AdminBundle\Entity\Shop sh WITH sh.userId = u.id
LEFT JOIN AdminBundle\Entity\Stand s WITH p.standId = s.standId
WHERE p.active = 1 and p.productId > 0";
How can I do this? I can't use native sql, becuase pagination (knpbundle) won't work.
That's not possible for security reasons ...
see this -> http://www.doctrine-project.org/jira/browse/DDC-885
eventually you can still make you subquery into a query and limit results with ->setMaxResults( XX ) , et use it into your main query.

Resources