I got the following code that gonna return the sum of score if tgl is '2023-01-01' and then that return value will be selected again to not show any null that the query find
SELECT *
FROM (
SELECT `kodeSales`,
`departemenId`,
`tgl`,
(SELECT SUM(CASE WHEN tgl IN ('2023-01-01') THEN score END)) AS '1'
FROM `history_penjualan`
WHERE `tgl` BETWEEN '2023-01-01' AND '2023-01-30'
`departemenId` = '28'
GROUP BY `tgl`
) AS temp
WHERE '1' IS NOT NULL
How do I do this in laravel eloquent or query builder ?
Try this way,
I tried this and it works. but in here you can change the ->having() statement as havingRaw("'1' IS NOT NULL") or I provided code also works.
$sum_of_score = DB::table('history_penjualan')
->select('kodeSales', 'departemenId', 'tgl', DB::raw("SUM(CASE WHEN tgl = '2023-01-01' THEN score END) AS '1'"))
->whereBetween('tgl', ['2023-01-01', '2023-01-30'])
->where('departemenId', '=', 28)
->groupBy('tgl')
->having('1', '!=', null)
->get();
If you want to learn about Laravel queries refer the document.
https://laravel.com/docs/9.x/queries
or if you need query in dynamic try this way,
$query = DB::table('history_penjualan')
->select(DB::raw('kodeSales, departemenId, tgl, SUM(CASE WHEN tgl = "2023-01-01" THEN score END) as "1"'))
->whereBetween('tgl', ['2023-01-01', '2023-01-30'])
->where('departemenId', '=', '28')
->groupBy('tgl');
$final_data = $query->having('1', '<>', null)->get();
If this is not your expected answer please leave a comment, I'll give another way to do this :)
Related
Im trying to do this SELECT IN SQL SERVER
SELECT cast(datediff(DAY, min([fbh].FBH_DATA_INICIAL), CASE
WHEN max([fbh].FBH_DATA_Final) = '9999-12-31' THEN cast(getdate() AS date)
ELSE max([fbh].FBH_DATA_Final)
END)AS FLOAT) / CAST(365 AS FLOAT) AS duration
FROM [funcionario] AS [f]
INNER JOIN [funcionario_banda_historico] AS [fbh] ON [f].[FUN_ID] = [fbh].[FUN_ID]
AND [f].[FUN_BANDA] = [fbh].[FUN_BANDA]
WHERE NOT EXISTS
(SELECT 1
FROM funcionario_banda_historico t1
WHERE t1.fun_id = [fbh].fun_id
AND t1.FBH_DATA_INICIAL > [fbh].FBH_DATA_Final
AND t1.FUN_BANDA <> [fbh].FUN_BANDA )
AND [f].[FUN_ID] = '9999999'
GROUP BY f.fun_id,
[f].[FUN_BANDA]
Im trying to do this select with where not in and select in LARAVEL
protected function getYearsInBand($userId) {
$fbh = DB::table('funcionario as f')
->join('funcionario_banda_historico as fbh', function($join) {
$join->on('f.FUN_ID', '=', 'fbh.FUN_ID');
$join->on('f.FUN_BANDA', '=', 'fbh.FUN_BANDA');
})
->selectRaw('cast(datediff(day,min([fbh].FBH_DATA_INICIAL),case when max([fbh].FBH_DATA_Final) = "9999-12-31" then cast(getdate() as date) else max([fbh].FBH_DATA_Final) end)AS FLOAT)/CAST(365 AS FLOAT) AS duration')
->where('f.FUN_ID', $userId)
->whereNotIn('1', function($q) {
$q->select('*')
->from('funcionario_banda_historico as t1')
->where('t1.fun_id = [fbh].fun_id')
->where('t1.FBH_DATA_INICIAL > [fbh].FBH_DATA_Final')
->where('t1.FUN_BANDA <> [fbh].FUN_BANDA')
->get();
})
->groupBy('f.FUN_ID', 'f.FUN_BANDA')
->first();
if (!$fbh) {
\Log::debug('funcionario_banda_historico not found'); // Grava no log
return 0;
}
return $fbh->duration;
}
and i had the error Invalid column name 'fun_id = [fbh]'
can you help me?
I think it's not correct syntax for "where" clause in Laravel. Instead you should do:
->whereRaw('t1.FUN_ID = fbh.FUN_ID')
->whereRaw('t1.FBH_DATA_INICIAL > fbh.FBH_DATA_Final')
->whereRaw('t1.FUN_BANDA <> fbh.FUN_BANDA')
OR:
->where('t1.FUN_ID', 'fbh.FUN_ID')
->where('t1.FBH_DATA_INICIAL', '>', 'fbh.FBH_DATA_Final')
->where('t1.FUN_BANDA', '<>', 'fbh.FUN_BANDA')
Notice that I also change "fun_id" to uppercase like everywhere in your code. I don't know if "[fbh]" is correct in Laravel, try to type just "fbh". For raw example you may also need to add Database prefix this way - "DB::getTablePrefix()"
I use laravel 5.3
My sql query is like this :
SELECT *
FROM (
SELECT *
FROM products
WHERE `status` = 1 AND `stock` > 0 AND category_id = 5
ORDER BY updated_at DESC
LIMIT 4
) AS product
GROUP BY store_id
I want to change it to be laravel eloquent
But I'm still confused
How can I do it?
In cases when your query is to complex you can laravel RAW query syntax like:
$data = DB::select(DB::raw('your query here'));
It will fire your raw query on the specified table and returns the result set, if any.
Reference
If you have Product model, you can run
$products = Product::where('status', 1)
->where('stock', '>', 0)
->where('category_id', '=', 5)
->groupBy('store_id')
->orderBy('updated_at', 'desc')
->take(4)
->get();
I think this should give you the same result since you pull everything from your derived table.
I want to write this query in laravel 5.2
SELECT b.id,
TotalP,
b.booking_amount
FROM booking b
LEFT JOIN
(SELECT sum(amount) AS TotalP,
booking_id
FROM payment
GROUP BY booking_id) AS T ON b.id = T.booking_id
WHERE COALESCE(TotalP, 0) < b.booking_amount
My Question is related to this post.
I wrote a query after searching and studying but It is not working and need more constraint
$result = DB::table('my_booking')
->select('booking_name')
->leftJoin(DB::raw('(SELECT booking_id,sum(amount) as TotalP FROM `my_payment` GROUP BY booking_id) TotalPayment'), function($join)
{
$join->on('my_booking.id', '=', 'TotalPayment.booking_id');
})
->get();
Sql query to get data diffrence of total in 2 tables
You can try this,
$booking_payments = Booking::with('Payment')->find(1);
$total = 0;
foreach($booking_payments->payment as $booking_payment){
$total += $booking_payment->amount;
}
if($booking_payments->booking_amount == $total){
// if the total and booking_amount is equal
}
This should work in Laravel and give you the same exact result as your MySQL query. I moved COALESCE into the subquery select area so that you don't have to write a raw DB where statement in Laravel.
$sql_subquery = "(SELECT COALESCE(SUM(amount),0) AS TotalP,
booking_id
FROM payment
GROUP BY booking_id) AS T";
$result = DB::table('booking AS b')
->leftJoin(DB::raw($sql_subquery), 'b.id', '=', 'T.booking_id')
->where('T.TotalP','<', 'b.booking_amount')
->select('b.id','T.TotalP','b.booking_amount')
->get();
Im trying days to understand how I can convert a SQL query to a query builder style in laravel.
My SQL query is:
$tagid = Db::select("SELECT `id` FROM `wouter_blog_tags` WHERE `slug` = '".$this->param('slug')."'");
$blog = Db::select("SELECT *
FROM `wouter_blog_posts`
WHERE `published` IS NOT NULL
AND `published` = '1'
AND `published_at` IS NOT NULL
AND `published_at` < NOW()
AND (
SELECT count( * )
FROM `wouter_blog_tags`
INNER JOIN `wouter_blog_posts_tags` ON `wouter_blog_tags`.`id` = `wouter_blog_posts_tags`.`tags_id`
WHERE `wouter_blog_posts_tags`.`post_id` = `wouter_blog_posts`.`id`
AND `id`
IN (
'".$tagid[0]->id."'
)) >=1
ORDER BY `published_at` DESC
LIMIT 10
OFFSET 0");
Where I now end up to convert to the query builder is:
$test = Db::table('wouter_blog_posts')
->where('published', '=', 1)
->where('published', '=', 'IS NOT NULL')
->where('published_at', '=', 'IS NOT NULL')
->where('published_at', '<', 'NOW()')
->select(Db::raw('count(*) wouter_blog_tags'))
->join('wouter_blog_posts_tags', function($join)
{
$join->on('wouter_blog_tags.id', '=', 'wouter_blog_posts_tags.tags_id')
->on('wouter_blog_posts_tags.post_id', '=', 'wouter_blog_posts.id')
->whereIn('id', $tagid[0]->id);
})
->get();
I have read that I can't use whereIn in a join. The error i now get:
Call to undefined method Illuminate\Database\Query\JoinClause::whereIn()
I realy dont know how I can convert my SQL to query builder. I hope when I see a good working conversion of my query I can understand how I have to do it next time.
This work for me:
DB::table('wouter_blog_posts')
->whereNotNull('published')
->where('published', 1)
->whereNotNull('published_at')
->whereRaw('published_at < NOW()')
->whereRaw("(SELECT count(*)
FROM wouter_blog_tags
INNER JOIN wouter_blog_posts_tags ON wouter_blog_tags.id = wouter_blog_posts_tags.tags_id
WHERE wouter_blog_posts_tags.post_id = wouter_blog_posts.id
AND id
IN (
'".$tagid."'
)) >=1")
->orderBy('published_at', 'desc')
->skip(0)
->take(10)
->paginate($this->property('postsPerPage'));
The following Query Builder code will give you the exact SQL query you have within your DB::select:
DB::table('wouter_blog_posts')
->whereNotNull('published')
->where('published', 1)
->whereNotNull('published_at')
->whereRaw('`published_at` < NOW()')
->where(DB::raw('1'), '<=', function ($query) use ($tagid) {
$query->from('wouter_blog_tags')
->select('count(*)')
->join('wouter_blog_posts_tags', 'wouter_blog_tags.id', '=', 'wouter_blog_posts_tags.tags_id')
->whereRaw('`wouter_blog_posts_tags`.`post_id` = `wouter_blog_posts`.`id`')
->whereIn('id', [$tagid[0]->id]);
})
->orderBy('published_at', 'desc')
->skip(0)
->take(10)
->get();
The subquery condition had to be reversed because you can't have a subquery as the first parameter of the where method and still be able to bind the condition value. So it's 1 <= (subquery) which is equivalent to (subquery) >= 1. The query generated by the above code will look like this:
SELECT *
FROM `wouter_blog_posts`
WHERE `published` IS NOT NULL
AND `published` = 1
AND `published_at` IS NOT NULL
AND `published_at` < Now()
AND 1 <= (SELECT `count(*)`
FROM `wouter_blog_tags`
INNER JOIN `wouter_blog_posts_tags`
ON `wouter_blog_tags`.`id` =
`wouter_blog_posts_tags`.`tags_id`
WHERE `wouter_blog_posts_tags`.`post_id` =
`wouter_blog_posts`.`id`
AND `id` IN ( ? ))
ORDER BY `published_at` DESC
LIMIT 10 offset 0
My process when creating more complex queries is to first create them and try them out in a SQL environment to make sure they work as indended. Then I implement them step by step with the Query Builder, but instead of using get() at the end of the query, I use toSql() which will give me a string representation of the query that will be generated by the Query Builder, allowing me to compare that to my original query to make sure it's the same.
I have been unsuccessfully trying to leftjoin and get the required data
Here is my code:
$album = Albums::->where('users_id',$user_id)
->leftJoin('photos',function($query){
$query->on('photos.albums_id','=','albums.id');
$query->where('photos.status','=',1);
//$query->limit(1);
//$query->min('photos.created_at');
})
->where('albums.status',1)->get();
The comments are some of my several trying...
I want to get only a single record from the photos table matching the foreign key album_id which was updated first and also with status 1
pls help...
I have used DB::raw() in order to achieve this
$album = Albums::select( 'albums.*',
DB::raw('(select photo from photos where albums_id = albums.id and status = 1 order by id asc limit 1) as photo') )
->where('users_id',$user_id)
->where('albums.status',1)->get();
#JarekTkaczyk 's coding was similar and displayed the same result as I needed, so a special thanks to him for his time and effort...
But comparing the execution time for the quires I stayed to mine as my above snippet
select `albums`.*, (select photo from photos where albums_id = albums.id and status = 1 order by id asc limit 1) as photo from `albums` where `users_id` = '1' and `albums`.`status` = '1'
took 520μs - 580μs
and #JarekTkaczyk 's
select `albums`.*, `p`.`photo` from `albums` left join `photos` as `p` on `p`.`albums_id` = `albums`.`id` and `p`.`created_at` = (select min(created_at) from photos where albums_id = p.albums_id) and `p`.`status` = '1' where `users_id` = '1' and `albums`.`status` = '1' group by `albums`.`id`
took 640μs - 750μs But both did the same...
You can achieve it using either leftJoin or rightJoin (but the latter would return Photo models, so probably you won't need that):
Albums::where('users_id', $user_id)
->leftJoin('photos as p', function ($q) {
$q->on('photos.albums_id', '=', 'albums.id')
->on('photos.updated_at', '=',
DB::raw('(select min(updated_at) from photos where albums_id = p.albums_id)'))
->where('photos.status', '=', 1);
})
->where('albums.status', 1)
->groupBy('albums.id')
->select('albums.*', fields from photos table that you need )
->get();
Are you trying to check for albums that have the status of '1'? If this is the case you are missing an equals sign from your final where.
Try:
->where('albums.status','=',1)->first();
Alternatively you may be able to achieve this with an 'on' instead of a 'where' inside the join function. You also don't need to split up query inside of the function and can do it as one line with the '->' :
$album = Albums::->where('users_id',$user_id)
->leftJoin('photos',function($query){
$query->on('photos.albums_id','=','albums.id')
->on('photos.status','=',1);
})
->where('albums.status','=',1)->first();
You need to make sure that you are using 'first', as it will return a single row of the first result. Get() will return an array.
As a straightforward answer which results in a single object I suggest the following query:
$album = DB::table('albums')->select('albums.*', 'photos.photo')
->join('photos', 'photos.id', '=', 'albums.id')
->where('users_id',$user_id)
->where('albums.status',1)
->first();