Laravel Eloquent Query Where IN statement - laravel

How do I convert this MySQL query to Laravel Eloquent Query:
SELECT * FROM service_package WHERE price IN ('110010', 'Test 02', '11009')

You can use the whereIn() like:
Using DB::table()
$data = \DB::table("service_package")
->whereIn("price", ['110010', 'Test 02', '11009'])
->get();
Using Eloquent
$data = App\ServicePackage::whereIn("price", ['110010', 'Test 02', '11009'])
->get();
Here, make sure you have created model ServicePackage for the table service_package.

Related

Laravel Query Builder in Model

I would like to know if is it possible to work in a model using query builder to make a join between 4 tables, I don't know how to use eloquent with 4 tables
this is in controller
$kurikulum = DB::table('siakad.tb_01')
->select('siakad.tb_01.*', 'siakad.krs_jadwal_aktiv.*', 'siakad.mata_kuliah.*', 'siakad.kurikulum_item.*', )
->join('siakad.krs_jadwal_aktiv', 'siakad.tb_01.staf_id', '=', 'siakad.krs_jadwal_aktiv.kdds')
->join('siakad.mata_kuliah', 'siakad.krs_jadwal_aktiv.kdmk', '=', 'siakad.mata_kuliah.kode')
->join('siakad.kurikulum_item', 'siakad.mata_kuliah.id', '=', 'siakad.kurikulum_item.mata_kuliah_id')
->get();
Please try this:
$kurikulum = DB::table('tb_01')
->select('tb_01.*', 'krs_jadwal_aktiv.*', 'mata_kuliah.*', 'kurikulum_item.*')
->join('krs_jadwal_aktiv', 'tb_01.staf_id','krs_jadwal_aktiv.kdds')
->join('mata_kuliah', 'krs_jadwal_aktiv.kdmk','mata_kuliah.kode')
->join('kurikulum_item', 'mata_kuliah.id','kurikulum_item.mata_kuliah_id')
->get();

Join table with its model's default scope in Laravel

Currently, we can join 2 tables like
ModelA::join('table_b', 'table_a.id', '=', 'table_b.a_id');
With this approach the default scopes on model for table_b (ie: ModelB) are not applied on query. Suppose the ModelB has SoftDeletes enabled now the above join won't include whereRaw('table_b.deleted_at IS NULL'). I know i can manualy add this using following code.
ModelA::join('table_b', function($join) {
$join->on('table_a.id', '=', 'table_b.a_id')
->whereRaw('table_b.deleted_at IS NULL');
});
I want to know if there is any method to join so that it automatically apply default scope(s) in ModeB. Something like:
ModelA::joinModel(ModelB::Class, 'table_a.id', '=', 'table_b.a_id');
I used the joinSub() function to join on a subquery. So following code worked for me:
ModelA::joinSub(ModelB::select('*'), 'table_b', function($join) {
$join->on('table_a.id', '=', 'table_b.a_id');
});
By using joinSub() I can also call other scopes on ModelB like:
ModelA::joinSub(ModelB::filterThis()->filterThat(), 'table_b', function($join) {
$join->on('table_a.id', '=', 'table_b.a_id');
});
Filter out the records on related Model, the Eloquent way -
ModelA::with('modelb')->whereHas('modelb', function($query){
$query->filterThis()->filterThat();
})->get();
Laravel QueryBuilder doesn't consider Eloquent scopes while running queries.
You can simple use Eloquent instead of Query Builder. With Eloquent it can be achieved like so:
ModelA::with('modelb')->get();
Where modelb is a HasMany relationship defined in ModelA.
The above statement will produce the following query:
select * from `modela` where `modelb`.`modela_id` in (1) and `modelb`.`deleted_at` is null

How can i write nested query in laravel

SELECT * FROM posts WHERE user_id IN (SELECT following FROM follows WHERE user_id='1'
This is the query i want to wirte in laravel to fetch the data how can i write this in laravel
This should work:
$result = DB::table('posts')
->whereIn('user_id', function ($query) {
$query->select('following')
->from('follows')
->where('user_id', 1);
})->get();

How to write sub query in Laravel eloquent

Following is my MySQL query
SELECT id
FROM member_measurement_records
WHERE date in (SELECT MAX(date) from member_measurement_records GROUP BY type)
Which I want to write using laravel eloquent.
Can you please help me. As I am new to this.
Well, there are several ways to do it.
Using DB facade
$data = DB::table('member_measurement_records')->where('date', DB::raw("(select max(`date`) from member_measurement_records GROUP BY type)"))->get();
Using eloquent and raw query
$data = MemberMeasurementRecords::whereRaw('date = (select max(`date`) from member_measurement_records GROUP BY type)')->get();
Using Eloquent and DB facade
$data = MemberMeasurementRecords::find(DB::table('member_measurement_records')->max('date')->groupBy('type'));
Haven't tested it, but you can try it:
(It is assumend your corresponding model is called MemberMeasurementRecords)
MemberMeasurementRecords::whereIn('date', function ($query) {
$query->max('date')->orderBy('type');
})->get('id');

Laravel 5.3 - multiple db queries when loading relations

I have posts table (id, user_id, title) and Post model with this content
class Post extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
I want to get some post by id and also the user's information, so I use this query
$post = new Post();
$res = $post->where('id', 1)->select('id', 'title', 'user_id')->with([
'user' => function ($query) {
$query->select('id', 'name', 'email');
}
])->first();
It returns the data as expected, and i can access the post's info like $res->title, or the user's info like $res->user->email, but the problem is it makes 2 queries to the database
I would expect to have one query only
SELECT
`posts`.`id`,
`posts`.`title`,
`posts`.`user_id`,
`users`.`id`,
`users`.`email`,
`users`.`name`
FROM
`posts`
LEFT JOIN `users`
ON `posts`.`user_id` = `users`.`id`
WHERE `posts`.`id` = '1'
LIMIT 1
Please note, this is not the same as N+1 problem
https://laravel.com/docs/5.3/eloquent-relationships#eager-loading
I know I can manually do left join,
$res = $post->where('posts.id', 1)
->select('posts.id', 'posts.title', 'posts.user_id', 'users.email', 'users.name')
->leftJoin('users', 'posts.user_id', '=', 'users.id')
->first();
and it will have the one query as I need, but the problem is in the result all data from related table is in the same array (and besides, what is the point of defining/using relationships if i have to manually make a left join every time)
So, my question is how to get the post data with related tables with one query and result organized according to relations: I am curious what is the best practice in laravel and how experienced Laravel developers are doing this ?
Thanks
Eloquent never uses JOINs to retrieve relationship data, but instead uses seperate queries and links the data together in PHP objects. Therefore, you will always have one extra query for each relationship. Also, Eloquent mostly loads all columns (using *).
To link them together, you have to stop using the query builder and instead use Eloquent directly:
$post = Post::find(1)->load('user');
If you insist on using JOINs, you will have to continue using the query builder.
That is eager loading.
You are using
->with([
'user' => function ($query) {
$query->select('id', 'name', 'email');
}
])
In eager loading, what happens is first run above query and get all the users matching the query.
Then the result is applied to the outer query which is
$post->where('id', 1)->select('id', 'title', 'user_id')->with([
'user' => function ($query) {
$query->select('id', 'name', 'email');
}
])->first();

Resources