How to transform this raw SQL query into Laravel Eloquent - laravel

This raw SQL query is returning the expected result on my SQL console. Would you please help me to transform it into a Laravel Eloquent query?
SELECT * FROM `my_services`
WHERE `user_id` = 1 and `financial_year` = '2021-2022'
AND (service_type = 'Return' OR service_type = 'Correction Return')
ORDER BY id DESC LIMIT 1,1;
I have tried to implement it like the following.
MyService::where([
'user_id' => $user->id,
'financial_year' => $request->financial_year,
'financial_year' => '2021-2022'
])
->orWhere(['service_type' => 'Return'])
->orWhere(['service_type' => 'Correction Return'])
->orderBy("id", "desc")
->offset(1)
->limit(1)
->get();

Try this query -
MyService::where('user_id', 1)->where('financial_year', '2021-2022')->where(function($q) {
$q->where('service_type', 'Return')->orWhere('service_type', 'Correction Return');
})->limit(1)->offset(1)->orderBy('id', 'DESC')->get();

From: https://laravel.com/docs/8.x/queries#limit-and-offset
Use ->skip(1) or ->offset(1) for offset
Use ->take(1) or ->limit(1) to limit count of returned results

Related

Laravel nested or with and in where condition

My Expected query is
select count(*) as aggregate from `books`
where (`books`.`is_deleted` = 0)
and `category_id` = '61'
and (`title` like '%問いかけの作法 チームの魅力と才能を引き出す技術%' or `title` like '%問イカケノ作法 チームノ魅力ト才能ヲ引キ出ス技術%' or `title` like '%問いかけの作法 ちーむの魅力と才能を引き出す技術%');
I have written my conditions like below ways
$queryCondition = $this::where(['books.is_deleted' => false]);
if( isset($queryString['category']) ){
$queryCondition->where('category_id',$queryString['category']);
}
if( isset($queryString['searchKey']) ){
$search = mb_convert_kana($queryString['searchKey'],"rns");
$kana = mb_convert_kana($search,"KVC");
$katakana = mb_convert_kana($search,"KVc");
$queryCondition->where('title','like','%'.$search.'%')
->orWhere('title','like','%'.$kana.'%')
->orWhere('title','like','%'.$katakana.'%')
;
}
I'm getting the output query like below
select count(*) as aggregate from `books`
where (`books`.`is_deleted` = 0)
and `category_id` = '61'
and `title` like '%問いかけの作法 チームの魅力と才能を引き出す技術%' or `title` like '%問イカケノ作法 チームノ魅力ト才能ヲ引キ出ス技術%' or `title` like '%問いかけの作法 ちーむの魅力と才能を引き出す技術%';
Without the () in last condition. How can I fix it ? Without this way has there any other ways to implement nested or in laravel ? Example
$query->where([
'OR' => [
[name LIKE' => '%'.$search.'%'],
[search LIKE' => '%'.$kana.'%'],
[search LIKE' => '%'.$katakana.'%']
]
]);
try this
->where(function ($query) {
$query->where('title','like','%問いかけの作法 チームの魅力と才能を引き出す技術%')
->orWhere('title','like','%問イカケノ作法 チームノ魅力ト才能ヲ引キ出ス技術%')
->orWhere('title','like','%問いかけの作法 ちーむの魅力と才能を引き出す技術%');
})
->get();
The closure will give you the () that you are seeking for.
Laravel documentation 9.x itself asks to add orwhere via above.
You should always group orWhere calls in order to avoid unexpected behavior when global scopes are applied.
From docs:
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere(function($query) {
$query->where('name', 'Abigail')
->where('votes', '>', 50);
})
->get();
which will give you,
select * from users where votes > 100 or (name = 'Abigail' and votes > 50)
You should try whereRaw with raw query instead of orWhere
So, instead of this
->orWhere('title','like','%'.$kana.'%')
->orWhere('title','like','%'.$katakana.'%');
Do this
->whereRaw('title LIKE "%$kana%" OR title LIKE "%$katakana%" ');
From my experience, anytime i use orWhere(), it ignores all other conditions so i prefer to use whereRaw and it works fine for me without any issues

How to add subquery in laravel query builder

I'm trying to convert my sql query to Laravel Query
From this
SELECT products.name,
(SELECT SUM(orders.date BETWEEN from_date AND to_date)
FROM orders WHERE orders.product_id = products.id ) as order_counts
FROM products;
Then I tried converting to laravel query builder but it results to an error:
Product::select('name',
DB::raw("SUM(orders.date
BETWEEN $request->from_date AND $request->to_date) AS total_orders
FROM orders WHERE orders.product_id = products.id"))
->get();
The error is syntax error on the $request->from_date inside db::raw.
You can use the withCount method: Documentation
Product::select('name')->withCount([
'orders' => function (Builder $query) using ($from_date, $to_date) {
$query->whereBetween('date', [$from_date, $to_date]);
}
]);
I saw you have edited your issue, and describe your error. When using variables in string you should put them in braces.
Product::select('name',
DB::raw(
"SUM(orders.date BETWEEN {$request->from_date} AND {$request->to_date}) AS total_orders FROM orders WHERE orders.product_id = products.id"
)
)->get();

Filter record through dates not working laravel

I have a expiry_date (type=date) column in my table
$currentDate = date('Y-m-d');
$Data = Post::whereDate('expiry_date','<=',$currentDate)->where(['status' => 'active'])->orWhere(['p_id' => 3])->select('id','title','status','p_id','expiry_date')->orderBy('id', 'DESC')->get();
i want to filter data if current date is greater than expiry date then those record should not be shown but in my scenario i'm still getting record.
Any solution Thanks.
You must group orWhere clause in closure. Grouping in closure is like () in real query.
$Data = Post::whereDate('expiry_date','<=',$currentDate)
->where(function($query){
return $query
->where(['status' => 'active'])
->orWhere(['p_id' => 3]);
})
->select('id','title','status','p_id','expiry_date')
->orderBy('id', 'DESC')
->get();
But, because I don't know your project - i may wrong with grouping.

Using DB raw Query in laravel

please assist to convert this SQL query into laravel format
"update user_names set assignedTo = '09874',Assigned=1 where timePackage='1 hr' and Assigned=0 order by id limit 1"
Try this:
use Illuminate\Support\Facades\DB;
DB::table('user_names')
->where('timePackage', '1 hr')
->where('Assigned', 0)
->orderBy('id')
->limit(1)
->update([
'assignedTo' => '09874',
'Assigned' => 1,
]);
See Laravel docs for more info.

How to select field in another table join by eager loading in Laravel

I got category_to_news and news_main table
category_to_news
news_id int
name varchar
title timestamp
news_main
id int
title varchar
image varchar
created_at timestamp
how to return by news_main's field and category_news's field ? I've tried this method and it's not work
$posts = Categorytonews::with(array(
'Newsmain' => function($query)
{
$query->orderBy('id', 'DESC')->select(array('title', 'id', 'created_at', 'image'));
}
))
->get( );
You need join for this because with() runs another query, so ordering there won't do the job:
$posts = Categorytonews::with('Newsmain') // get all fields from Newsmain
->join('news_main', 'category_to_news.news_id', '=', 'news_main.id') // join for ordering
->orderBy('news_main.id','desc') // order by joined field
->get('category_to_news.*'); // select only main table, you don't need joined fields
// on Categorytonews model - they will be loaded by with()
$posts = Categorytonews::with(array('Newsmain' => function($query)
{
$query->select(array('title', 'id', 'created_at', 'image'))->orderBy('id', 'DESC');
}))->get();

Resources