Laravel Backpack Query Builder select value or is null - php

I'm using backpack CRUD for laravel and i'm trying to request my database. My problem is how can i join tables on values or null ?
this is what i want
select * from `baskets`
inner join `users` on `baskets`.`donor_id` = `users`.`id`
inner join `users` as `ass` on `baskets`.`association_id` = `ass`.`id` or `baskets`.`association_id` is null
where `users`.`_lft` >= 1 and `users`.`_rgt` <= 1000
group by `baskets`.`basket_id`
order by `baskets`.`basket_id` desc, `end_removal_date` desc
And this is what i'm trying to do with the query builder
$this->crud->query->join('users', 'baskets.donor_id', '=', 'users.id');
$this->crud->query->join('users as ass', function($join){
$join->on('baskets.association_id', '=', 'ass.id');
$join->orOn('baskets.association_id', 'is', \DB::raw('null');
}
$this->crud->addClause('where', 'users._lft', '>=', Auth::user()->_lft);
$this->crud->addClause('where', 'users._rgt', '<=', Auth::user()->_rgt);
Of course not working.
Have you got an idea ?
Thanks

Use this:
$join->orWhereNull('baskets.association_id');

Related

How to select from a table based on another table's values Eloquent?

I am trying to get the data on some students that are still active. Even tho I have data from inactive students in the same table.
This is the StudentAttendance
This is the StudentClass
This is the Eloquent query that I came up with:
StudentAttendance::
select('student_classes.active', 'student_attendances.student_id', 'student_attendances.classroom_id', 'classrooms.classroom', 'attendance_rules.option')
->join('classrooms', 'classrooms.id', '=', 'student_attendances.classroom_id')
->join('attendance_rules','attendance_rules.id', '=', 'student_attendances.attendance_id')
->join('student_classes', 'student_attendances.student_id', '=', 'student_classes.student_id')
->where('attendance_date', date("Y-m-d"))
->orderBy('classrooms.classroom', 'ASC')
->get();
SQL:
select `student_classes`.`active`, `student_attendances`.`student_id`, `student_attendances`.`classroom_id`, `classrooms`.`classroom`, `attendance_rules`.`option`
from `student_attendances`
inner join `classrooms` on `classrooms`.`id` = `student_attendances`.`classroom_id`
inner join `attendance_rules` on `attendance_rules`.`id` = `student_attendances`.`attendance_id`
inner join `student_classes` on `student_attendances`.`student_id` = `student_classes`.`student_id`
where `attendance_date` = '2020-02-11'
order by `classrooms`.`classroom` asc
Now my Eloquent query results into this:
As you can see the student_id 22 with the classroom_id of 2 is inactive but it appears to be inactive once and the rest active. If I remove the student_classes join I won't get all the repeated results.
The goal is to display all the attendances of today where the student is active (active=1) in the StudentClass even if I query in the StudentAttendance.
You will want to scope your join to student_classes to only look at active records.
You can do this by using a callback in your join method:
->join('student_classes', function ($join) {
$join->on('student_attendances.student_id', '=', 'student_classes.student_id')
->on('student_classes.classroom_id', '=', 'student_attendances.classroom_id')
->where('student_classes.active', 1);
})
This is covered under the 'Advanced Join Clauses' in the Query Builder docs - https://laravel.com/docs/5.8/queries#joins

Three join and groupby ln laravel 5.4

Hello I am new with laravel and I need to do two join between three tables then group by and count in another table then join the result of the group by with the two join result.I try to use two query the first one for the two join and the second query for the group by but i don't know how to join the two query.
This is my first query three tables: members, members_courses_assign and courses
$temp = DB::table('members')
->join('members_courses_assign', 'members.externalPersonKey', '=', 'members_courses_assign.externalPersonKey')
->join('courses', 'members_courses_assign.referenceNumber', '=', 'courses.referenceNumber')->where(['courses.termkey'=>$termK,'members_courses_assign.termkey'=>$termK])->get();
This is my second query
$count= DB::table('files')
->select('referenceNumber', DB::raw('count(*) as total'))
->where(['termkey'=>$termK])
->groupBy('referenceNumber')
->get();
Then i need to join the result of the first with the second, I try to join the 4 table first but the 4th table 'files' will ambiguity because the 'referenceNumber' is'not unique in the 'files' table.
If I understand what you are trying to do, using join() with the 'count' subquery as the first argument, and passing a Closure as the second argument specifying the link between your main query and the subquery should work.
$temp = DB::table('members')
->join('members_courses_assign', 'members.externalPersonKey', '=', 'members_courses_assign.externalPersonKey')
->join('courses', 'members_courses_assign.referenceNumber', '=', 'courses.referenceNumber')
->join(DB::raw('(SELECT COUNT(*) AS count, referenceNumber FROM files WHERE termkey='.$termK.' GROUP BY referenceNumber) FileCount'), function($join)
{
$join->on('courses.referenceNumber', '=', 'FileCount.referenceNumber');
})
->where(['courses.termkey'=>$termK,'members_courses_assign.termkey'=>$termK])
->get();

how to convert inner query in select to eloquent laravel 5.4

I have a query like this..
select *,
case l.user_type
when '0' then
(select CONCAT(first_name,'',last_name) from users where id=l.user_id)
when '1' then
(select party_name from tbl_partys where id=l.user_id)
end as user_name
from tbl_leased_comm l
where l.user_id=$party and l.user_id=$user_id
order by l.updated_at desc
How to convert this query to laravel query
help me, anyone...
Yeah it works for me
as,
DB::table('tbl_leased_comm')
->select(["*",
DB::raw("case tbl_leased_comm.user_type when '0' then (select CONCAT(first_name,'',last_name) from users where id=tbl_leased_comm.user_id) when '1' then (select party_name from tbl_partys where id=tbl_leased_comm.user_id) end as user_name")])
->where('tbl_leased_comm.user_id','=',$party )
->where('tbl_leased_comm.user_id','=',$user_id)
->orderBy('tbl_leased_comm.updated_at', 'desc')
->get();
Thanks a lot..
reference link:Convert mysql query logic to Laravel query builder

how to count items on laravel query?

i need to count hours. this is my laravel eloquent:
$items = Item::ofType('type')->where('start_at','>=',Carbon::today())->groupBy(\DB::raw('HOUR(start_at)'))->count();
And this is show me results like 2/2/1
sql query of this:
SELECT
count(*)AS AGGREGATE
FROM
`items`
WHERE
`type` = 'type'
AND `start_at` >= '2015-10-15 00:00:00'
GROUP BY
HOUR(start_at)
And how to count 2/2/1 of this and get result = 3?
I need laravel eloquent without RAW.
EDIT:
SELECT COUNT(*) FROM (SELECT
count(*) AS AGGREGATE
FROM
`items`
WHERE
`type` = 'type'
AND `start_at` >= '2015-10-15 00:00:00'
GROUP BY
HOUR(start_at)) as count
how to write this in laravel eloquent?
you can use this code check laravel documentation on this link. http://laravel.com/docs/4.2/queries
Order By, Group By, And Having
$users = DB::table('items')
->orderBy('name', 'desc')
->groupBy('count')
->having('count', '>', 100)
->get();

How to order grouped results by last id using Eloquent and MySQL?

I tried this query but it only order id column, rest is not.
$chapters = Test::select(DB::raw('*, max(id) as id'))
->groupBy('id_equip')
->orderBy('id', 'asc')
->get();
In MySQL when using group by you can't rely on order by clause (it won't work as you expect, ie. it will not order the results in groups, but rather return random row from the group).
So in order to achieve what you want, you need a subquery or join:
// assuming tests table, group by id_equip, order by id
SELECT * FROM tests WHERE id = (
SELECT MAX(id) FROM tests as t WHERE t.id_equip = tests.id_equip
) ORDER BY id
SELECT * FROM tests
JOIN (SELECT MAX(id) as id FROM tests ORDER BY id DESC) as sub
ON sub.id = tests.id
This will get the highest id for each id_equip and return whole row for each of them.
Now, in eloquent I suggest first approach, if you want it to look more intuitive:
Test::where('id', function ($sub) {
// subquery
$sub->selectRaw('max(id)')
->from('tests as t')
->where('t.id_equip', DB::raw('tests.id_equip'));
// order by
})->orderBy('id', 'desc')->get();
but 2nd appreach is probably the way if you have big table to scan (in terms of performance):
Test::join( DB::raw(
'(select max(id) as id from tests group by id_equip order by id desc) sub'
), 'sub.id', '=', 'posts.id')
->get(['tests.*']);
Here you need to set order by clause inside the raw join statement.
You could also build that join subquery with the builder if you like:
$sub = Test::selectRaw('max(id)')
->groupBy('id_equip')
->orderBy('id', 'desc')
->toSql();
Test::join( DB::raw(
"({$sub}) as sub"
), 'sub.id', '=', 'posts.id')
->get(['tests.*']);

Categories