how to convert below SQL query in Laravel query? - laravel

how to convert below sql query in laravel
SELECT `models`.* FROM (
(SELECT * FROM `models` WHERE `models`.`fk_car_model_id` = 3 LIMIT 5)
UNION ALL
(SELECT * FROM `models` WHERE `models`.`fk_car_model_id` = 2 LIMIT 3)
UNION ALL
(SELECT * FROM `models` WHERE `models`.`fk_car_model_id` = 1 LIMIT 2)
) AS `models`

// if you want to get all the fields, you can use the following:
$fields = '*';
// if you want to select only some fields, use this:
// $fields = [
// 'id',
// 'fk_car_model_id',
// ];
$data = Model::select($fields)
->where('fk_car_model_id', 3)->limit(5)
->unionAll(
Model::select($fields)
->where('fk_car_model_id', 2)->limit(3)
)
->unionAll(
Model::select($fields)
->where('fk_car_model_id', 1)->limit(2)
)
->get()
->toArray();
return $data;
Or you can use something like this:
$query = DB::table('models')
->select('models.*')
->where('models.fk_car_model_id', '=', 3)
->limit(5)
->unionAll(
DB::table('models')
->select('models.*')
->where('models.fk_car_model_id', '=', 2)
->limit(3)
)
->unionAll(
DB::table('models')
->select('models.*')
->where('models.fk_car_model_id', '=', 1)
->limit(2)
)
->get();

Please check it, this might help you. This might not b exact as you want but you can get some idea about its working and change as per you requirements.
Model::where(function ($query) {
$query->where('fk_car_model_id', '=', 3)
->limit(5)
})->orWhere(function ($query) {
$query->where('fk_car_model_id', '=', 2)
->limit(3)
})->orWhere(function ($query) {
$query->where('fk_car_model_id', '=', 1)
->limit(2)
})->get();
See more for Documentation for reference Logical Grouping

Related

select from table (laravel) - where and orWhere

So, I'm using laravel and I want to make this query to work in laravel 'formula'
SELECT * FROM `complaints` WHERE (`fID` = 0) AND (`hide_topic` = 0 OR (`hide_topic` <= 0 OR (`hide_topic` > 3 AND byID = 52))) ORDER BY `status` ASC, `id` DESC
And I made something like this in laravel but not sure that selects correctly like the query above does.
DB::table('complaints')
->where('fID', '=', 0)
->where('hide_topic', '=', 0)
->orWhere('hide_topic', '<', 0)
->orWhere('hide_topic', '>', 3)
->where('byID', '=', 52)
->orderBy('status', 'asc')
->orderBy('id', 'desc')
->get();
Any help?
If you carefully examine your query. You can definitely remove some extra filters. If you see inner where if hide_topic <= 0 it also covers hide_topic =0 so you can reduce your query to.
SELECT *
FROM `complaints`
WHERE `fID` = 0
AND (`hide_topic` <= 0 OR (`hide_topic` > 3 AND byID = 52))
ORDER BY `status` ASC, `id` DESC
Best thing from laravel is that you can actually see the query that will be executed using query builders or eloquent model using toSql method. You can use toSql method at place of get, all or first functions.
$result = DB::table('complaints')
->where('fID', '=', 0)
->where(function($query) {
$query->where('hide_topic', '<=', 0)
->orWhere(function($query) {
$query->where('hide_topic', '>', 3)
->where('byID', '=', 52);
});
})
->orderBy('status', 'asc')
->orderBy('id', 'desc')
->get();
// to check the query just replace `->get();` to `->toSql();` in above query.
Now if you don't want any modifications in your existing query. You can reference to #OMR answer. Still I'll put it here.
$result = DB::table('complaints')
->where('fID', '=', 0)
->where(function($query) {
$query->where('hide_topic', '=', 0)
->orWhere(function($query) {
$query->where('hide_topic', '<=', 0)
->orWhere(function($query) {
$query->where('hide_topic', '>', 3)
->where('byID', '=', 52);
});
});
})
->orderBy('status', 'asc')
->orderBy('id', 'desc')
->get(); -- use toSql() to actually see the query before bindings.
you simply use where with clouser for every compound condition:
$admin_level=3;
$playerid=52;
DB::table('complaints')->where('fID', '=', 0)
->where(function ($query)use($admin_level,$playerid){
$query->where('hide_topic', '=', 0)->orWhere(function ($query)use($admin_level,$playerid){
$query->Where('hide_topic', '<', 0)->orWhere(function ($query)use($admin_level,$playerid){
$query ->Where('hide_topic', '>', $admin_level)
->where('byID', '=', $playerid);
});
});
})
->orderBy('status', 'asc')
->orderBy('id', 'desc')
->get();

Laravel 5.6 Or Query Multiple in where

This is my filter query function
$keywords = [];
foreach($columns as $key => $value){
$keywords[] = [$key, 'LIKE', '%'.$value.'%'];
}
$query= $this->model ->orderBy('name', 'asc')->where('is_deleted', 0)->Where($keywords);
if($status=="yes")
$query= $query->where('status',1);
$query= $query->get();
return $query;
For the above function, i got the following query
select * from stores where is_deleted = 0 and status = 1 AND (name LIKE %r% AND address LIKE %r%) order by name asc
But i need Or instead of ANd in the like query
select * from `stores` where `is_deleted` = 0 and `status` = 1 AND (`name` LIKE %r% or `address` LIKE %r%) order by `name` asc
Please tell in which place i need to change?
You can use Where and orWhere.
$query= $this->model->orderBy('name', 'asc')->where('is_deleted', 0)->
orWhere($key, 'LIKE', '%'.$value.'%');
You have to group those orWhere() queries in one where() clause
$query = $this->model->where([
['is_deleted' => 0],
['status' => $status]
])
->where(function ($query) use($columns) {
foreach($columns as $key => $value) {
$query->orWehre($key, 'like', "%$value%");
}
})
->orderBy('name');

Convert SQL into Laravel Eloquent

I have this SQL query:
SELECT
m1.id
FROM
messages m1
WHERE
m1.to_id = 1 AND m1.created_at < (
SELECT
m2.created_at
FROM
messages m2
WHERE
m2.from_id = m1.to_id AND m2.to_id = m1.from_id)
GROUP BY
m1.id
How can i convert into eloquent? I done this until now, but a don't know what to do in the part of where on subquery.
Message::where('to_id', 1)
->where('created_at', '<', function($q) {
$q->from('messages');
$q->select('created_at');
})
->select('id')
->groupBy('id')
->get();
You can try this:
Message::where('to_id', 1)
->where('created_at', '<', function($q) {
$q->from('messages AS m2')
->select('created_at')
->where('m2.from_id ','=', 'messages.to_id ')
->where('m2.to_id','=','messages.from_id');
})
->select('id')
->groupBy('id')
->get();

Why query returns empty collection?

I have the following query was built by Laravel:
$res = Announcement::whereExists(function ($query) {
$query->select(DB::raw(1))
->from('announcement_category')->join('user_category', 'user_category.category_id', '=', 'announcement_category.category_id')
->where('user_category.user_id', '=', 1)
->where('announcement_category.announcement_id', '=', 'announcements.id');
});
dd($res->get());
The code above gives me empty collection: dd($res->get());.
The plain SQL code of this query is:
select * from `announcements` where exists (select 1 from
`announcement_category` inner join `user_category` on
`user_category`.`category_id` = `announcement_category`.`category_id` where `user_category`.`user_id` = 1
and `announcement_category`.`announcement_id` = announcements.id)
and `announcements`.`deleted_at` is null
If execute this directly in MySQL, I get two result rows.
But why dd($res->get()); retuns me empty?
I don't think there is a whereExists in eloquent model... try this:
$res = DB::table('announcement')->whereExists(function ($query) {
$query->select(DB::raw(1))
->from('announcement_category')->join('user_category', 'user_category.category_id', '=', 'announcement_category.category_id')
->where('user_category.user_id', '=', 1)
->where('announcement_category.announcement_id', '=', 'announcements.id');
})->get();

Query builder with max()

I am trying to rewrite this sql to laravel 4
SELECT
*
FROM
SolutionFile
WHERE
SolutionFile.group_id = $group_id and
version = (
SELECT
max(s1.version)
FROM
SolutionFile s1
WHERE
s1.group_id = $group_id
)
I wrote this request
SolutionFile::where('group_id', '=', $group_id)
->whereRaw('version = (select max(`version`) from files where group_id = ' . $group_id . ')')->get();
which works perfectly, but I want to rewrite it in "laravel way" without whereRaw.
I tried this request
SolutionFile::where('group_id', '=', $group_id)
->where(function($query) use($group_id) {
return $query->where('version', '=', function() use($group_id) {
return SolutionFile::where('group_id', '=', $group_id)->max('version');
});
});
but it returns an empty set.
Is there any way to rewrite it? Where did I make a mistake in last request?
I found simple solution for this
SolutionFile::where('group_id', '=', $group_id)
->where(function($query) use($group_id) {
return $query->where('version', '=', SolutionFile::where('group_id', '=', $group_id)->max('version'));
})->get()
There was no need to use function() as third param, only result from this function.

Resources