how to count items on laravel query? - php

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();

Related

Convert Raw SQL 'NOT' IN (too slow) to Laravel Eloquent

I have a running script using Raw SQL in Laravel 5.3 controller which I found it slow and not secure ( as Raw ). If there any way to make it more effecient and convert it to eloquent or Query Builder for Laravel ?
code as below & Thanks !
SELECT machine_code, machine_name
FROM factory_equipment
WHERE machine_code NOT IN
(
SELECT distinct(machine_code)
FROM echecklist_data
WHERE DATE_FORMAT(date, '%Y-%m-%d') = CURDATE()
)
AND type='production' ORDER BY machine_code ASC
You can make it more efficient using SQL. I would recommend NOT EXISTS:
SELECT fe.machine_code, fe.machine_name
FROM factory_equipment fe
WHERE NOT EXISTS (SELECT 1
FROM echecklist_data ed
WHERE ed.machine_code = fe.machine_code AND
ed.date >= CURDATE() AND
ed.date < CURDATE() + INTERVAL 1 DAY
) AND
fe.type = 'production'
ORDER BY fe.machine_code ASC;
I would further recommend indexes on: factory_equipment(type, machine_code, machine_name) and echecklist_data(machine_code, date).
You can speed up this query by making it into a LEFT JOIN and selecting only rows which have no match in the echecklist_data table:
SELECT fe.machine_code, fe.machine_name
FROM factory_equipment fe
LEFT JOIN echecklist_data ed ON ed.machine_code = fe.machine_code AND DATE_FORMAT(ed.date, '%Y-%m-%d') = CURDATE()
WHERE fe.type='production' AND ed.machine_code IS NULL
ORDER BY fe.machine_code ASC
Note that if your date column is a DATETIME type, then using DATE(ed.date) = CURDATE() will also be more efficient than DATE_FORMAT(ed.date, '%Y-%m-%d') = CURDATE().
I managed to get it working using laravel's query. Hope it helps others
DB::table('factory_equipment')
->select('factory_equipment.machine_code', 'factory_equipment.machine_name')
->leftjoin('echecklist_data', function ($leftjoin) {
$leftjoin->on('factory_equipment.machine_code', '=', 'echecklist_data.machine_code')
->Where( DB::raw("DATE_FORMAT(echecklist_data.date, '%Y-%m-%d')"), DB::raw("CURDATE()") );
})
->where('factory_equipment.type' , '=', 'production')
->whereNull('echecklist_data.machine_code')
->get();

Laravel Backpack Query Builder select value or is null

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');

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 convert sql query to eloquent laravel?

how to convert simple mysql query to eloquent laravel?
in fact I want to convert down query :
SELECT temp.* FROM
(SELECT * FROM avilableproducts ORDER BY avilableproducts.count DESC) AS temp
GROUP BY temp.products_id, temp.color
HAVING temp.products_id = 27
ORDER BY temp.count DESC;
to
$Avilableproducts = $Avilableproducts->select(DB::raw('temp.*'))
->from(DB::raw('(SELECT * FROM avilableproducts ORDER BY count DESC) AS temp'))
->groupBy(['products_id', 'color'])
->orderBy('count', 'desc');

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