Doctrine 2: QueryBuilder Join with subquery - php

I need to convert native query to doctrine query.
Native query
select u.*, v.browser_id
from users u
left join visits v
on u.id = v.user_id
and v.id = (
select max(id) from visits v2
where v2.user_id = u.id
)
You can see right here that I need to select users with the latest browser they used to visit
So to convert this query to DQL I understand that I need to do something like this
$queryBuilder->leftJoin('u.visits', 'lastVis', Join::WITH,
// ????
);
but I don’t know what exactly. Perhaps someone will solve this quickly?

Thanks, seem I found the solution:)
$subQuery = $this->entityManager->createQueryBuilder()
->select('MAX(vis2.id)')
->from(Visit::class, 'vis2')
->where('vis2.user = u.id');
$this->entityManager->createQueryBuilder()
->select('u')
->from(User::class, 'u')
->leftJoin(
'u.visits', 'vis',
Join::WITH, sprintf('vis.id = (%s)', $subQuery->getDQL()),
);

Related

Laravel Self join Query

I am trying to execute a self join query in Laravel. I am getting while i try to execute the same as raw query
$data['d_meetings'] =DB::select("select t1.*,t2.* from `leads_followup_details` as `t1` inner join `leads_followup_details` as `t2` on `t1`.`leads_enquiry_details_enquiry_id` = `t2`.`leads_enquiry_details_enquiry_id` inner join `leads_enquiry_details` on `enquiry_id` = `t1`.`leads_enquiry_details_enquiry_id` where `t1`.`followup_meeting` = 'direct' and t1.followup_id<t2.followup_id and t1.followup_next_followup_date=t2.followup_date and `t2`.`followup_current_meeting` = 'direct' and `enquiry_deleted` = 1 group by `t1`.`followup_id`");
$data['d_meetings'] = DB::table('leads_followup_details as t1')
->join('leads_followup_details as t2', 't1.leads_enquiry_details_enquiry_id', 't2.leads_enquiry_details_enquiry_id')
->where('t2.followup_id', '>', 't1.followup_id')
->where('t2.followup_id', '!=', 't1.followup_id')
->whereDate('t1.followup_next_followup_date', '=', 't2.followup_date')
->where('t1.followup_meeting', 'direct')
->join('leads_enquiry_details', 'enquiry_id', 't1.leads_enquiry_details_enquiry_id')->where('enquiry_deleted', 1)
->groupBy('t1.followup_id')->get();
but this is not working as my expectation .
Please help
You can try:
$data['d_meetings'] = DB::table('leads_followup_details as t1')
->select('t1.followup_id', 't2.followup_id', 't1.followup_next_followup_date', 't2.followup_date', 't2.followup_current_meeting', 't1.followup_meeting')
->join('leads_followup_details as t2','t1.leads_enquiry_details_enquiry_id','t2.leads_enquiry_details_enquiry_id')
->join('leads_enquiry_details','enquiry_id','t1.leads_enquiry_details_enquiry_id')
->where('t1.followup_id','<','t2.followup_id')
->where('t1.followup_id','<>','t2.followup_id')
->where('t1.followup_next_followup_date','=','t2.followup_date')
->where('t1.followup_meeting', 'direct')
->where('t2.followup_current_meeting', 'direct')
->where('enquiry_deleted',1)
->groupBy('t1.followup_id')->get();
I see you miss t2.followup_current_meeting ='direct'
It seems that your ->whereDate('t2.followup_date','=','t2.followup_next_followup_date')
doesn't match your SQL and t1.followup_next_followup_date=t2.followup_date
It might be easier if you write out the Laravel query in the same order as the SQL (and observe the re-added ->where('t2.followup_current_meeting', 'direct')):
$data['d_meetings'] = DB::table('leads_followup_details as t1')
->join('leads_followup_details as t2',
't1.leads_enquiry_details_enquiry_id',
't2.leads_enquiry_details_enquiry_id')
->join('leads_enquiry_details','enquiry_id',
't1.leads_enquiry_details_enquiry_id')
->where('t1.followup_id','<>','t2.followup_id')
->where('t1.followup_id','<','t2.followup_id')
->where('t1.followup_meeting', 'direct')
->where('t2.followup_current_meeting', 'direct')
->whereDate('t1.followup_next_followup_date','=',
't2.followup_date')
->where('enquiry_deleted',1)
->groupBy('t1.followup_id')->get();

Left join 2 times raw query laravel doesn't work (Laravel)

I tried my raw query sql in laravel and i need to left join it 2 times but the print out is wrong. It different from mysql. I've tried in mysql and it works well
this is my code :
$tabel = DB::SELECT(DB::RAW("
SELECT codeh.info_code kh_infocode, codep.no_code khp_nocode,
codep.info_code khp_infocode,
codep.name_code khp_namecode, t.* FROM transactions t
LEFT JOIN users u ON t.user_id=u.id
LEFT JOIN divisions d ON d.id=u.division_id
LEFT JOIN all_codes codep ON t.code_p_id=codep.id
LEFT JOIN all_codes codeh ON t.allcode_id=codeh.id
WHERE 1=1
AND d.id=$div_id
AND codep.no_code LIKE '$allcode->no_code%'
$db_date
ORDER BY t.date, khp_nocode
"));
it works really well in sql but when i put it in laravel kh_infocode change and the value same like khp_infocode even though kh_infocode has different value with khp_infocode
Everything is in the official docs. It's not even long, go give it a read.
DB::table('transactions as t')
->select(
'codeh.info_code',
'kh_infocode',
'codep.no_code',
'khp_nocode',
'codep.info_code',
'khp_infocode',
'codep.name_code',
'khp_namecode',
't.*',
)
->leftJoin('users as u', 't.user_id', '=', 'u.id')
->leftJoin('all_codes as codep', 't.code_p_id', '=', 'codep.id')
->leftJoin('all_codes as codeh', 't.allcode_id', '=', 'codeh.id')
->where('d.id', '=', $div_id)
->where('codep.no_code', 'like', $allcode->no_code.'%')
->orderBy('t.date')
->orderBy('khp_nocode')
->get();
simply set SQL string directly without DB::RAW()
$tabel = DB::SELECT('your select statment');

Write SQL sum with join and group by in Laravel?

I wish to write a query from SQL Server to laravel.
I want to write like this SQL:
select SUM(TRANSTKD.TRD_U_PRC) as prctotal from DOCINFO
inner join [TRANSTKH] on [DOCINFO].[DI_KEY] = [TRANSTKH].[TRH_DI]
inner join [SKUMASTER]
inner join [TRANSTKD]
on [TRANSTKD].[TRD_SKU] = [SKUMASTER].[SKU_KEY]
on [TRANSTKH].[TRH_KEY] = [TRANSTKD].[TRD_TRH]
where [DOCINFO].[DI_KEY] = 148978
GROUP BY [SKUMASTER].[SKU_CODE];
Try this below laravel query
DB::table('DOCINFO')
->join('TRANSTKH', 'DOCINFO.DI_KEY', '=', 'TRANSTKH.TRH_DI')
->join('TRANSTKD', 'TRANSTKH.TRH_KEY', '=', 'TRANSTKD.TRD_TRH')
->join('SKUMASTER', 'TRANSTKD.TRD_SKU', '=', 'SKUMASTER.SKU_KEY')
->select(DB::raw('SUM(TRANSTKD.TRD_U_PRC) as prctotal'))
->where('DOCINFO.DI_KEY',148978)
->groupBy('SKUMASTER.SKU_CODE')
->get();
Let me know how it helps you!

Laravel query builder with joins

I am blocked in the conversion of my raw sql query to laravel query builder. Can someone give me a hand on the issue?
select p.name, p.`type`, p.`status`, p.state, ps1.* from pos_session ps1 right join pos p on ps1.pos_id = p.id where ps1.id = (select max(ps0.id) from pos_session ps0 where ps0.pos_id = ps1.pos_id) or p.site_id = '2' order by ps1.pos_id;
Try following query:
DB::table('pos_session AS ps1')
->select('p.name','p.type','p.status','p.state','ps1.*')
->rightJoin('pos AS p','ps1.pos_id','=','p.id')
->where('ps1.id','=',function($query){
$query->select(DB::raw('MAX(ps0.id)'))
->from('pos_session AS ps0')
->where('ps0.pos_id','=','ps1.pos_id');
})
->orWhere('p.site_id','=',2)
->orderBy('ps1.pos_id')
->get();
you can achieve the results through join as well:
DB::table('pos_session AS ps1')
->select('p.name','p.type','p.status','p.state','ps1.*')
->rightJoin('pos AS p','ps1.pos_id','=','p.id')
->join('pos_session AS ps0', 'ps0.pos_id', '=', 'ps1.pos_id')
->where('ps1.id','=',DB::raw('MAX(ps0.id)'))
->orWhere('p.site_id','=',2)
->orderBy('ps1.pos_id')
->get();
Hope it helped :)

Doctrine query "where notIn" subquery issue

In Symfony2, I have a many:many relationship between users and roles.
I am trying to get a list of all the users which are not linked to the ROLE_SUPER_ADMIN role.
Before migrating to Symfony2/Doctrine, I had achieved this with a simple NOT IN sql query, but for the life of me I can't achieve the same effect with doctrine.
Here is what I am trying:
$em = $this->getDoctrine()->getManager();
$qb = $em->createQueryBuilder();
$qb2 = $qb;
$dql = $qb->select('sa.id')
->from('AcmeAdminBundle:User', 'sa')
->leftJoin('sa.roles', 'r')
->andWhere('r.role = :role')
->getDQL();
$result = $qb2->select('u')
->from('AcmeAdminBundle:User', 'u')
->where($qb2->expr()->notIn('u.id', $dql))
->setParameter('role', 'ROLE_SUPER_ADMIN')
$users = $result->getQuery()->getResult();
But this is the error:
[Semantical Error] line 0, col 140 near 'sa LEFT JOIN':
Error: 'sa' is already defined.
And this is the output:
SELECT u
FROM AcmeAdminBundle:User sa
LEFT JOIN sa.roles r, AcmeAdminBundle:User u
WHERE u.id NOT IN (
SELECT sa.id
FROM AcmeAdminBundle:User sa
LEFT JOIN sa.roles r
WHERE r.role = :role
)
No idea why it is outputting like that as it should not be performing LEFT JOIN two times, my suspicion is that it has something to do with having two QueryBuilder instances, but could be something else entirely.
You need the MEMBER OF or in your case NOT MEMBER OF option.
$qb->select('sa.id')
->from('AcmeAdminBundle:User', 'sa')
->where(":Role NOT MEMBER OF sa.roles")
->setParameter("Role", <<ROLE_ID_OR_ROLE_ENTITY>>);
I didn't test this code, but it should give you some idea.
Full documentation can be found at http://docs.doctrine-project.org/en/latest/reference/dql-doctrine-query-language.html

Categories