I have no data with joined ad_categories table - laravel

In laravel 8 I make request with condition on joined ad_categories table :
$adsCategories = [1,2,3,4,6,7,8];
$data = Ad
::whereDate('expire_date', '>=', $date_start)
->whereDate('expire_date', '<', $date_end)
->orderBy($order_by, $order_direction)
->with('adCategories')
->with('creator')
->withCount('adLocations')
->leftJoin('ad_categories', 'ad_categories.ad_id', '=', 'ads.id')
->whereIn('ad_categories.category_id', $adsCategories)
->get();
and tracing sql :
SELECT `ads`.*, ( SELECT count(*)
FROM `ad_locations`
WHERE `ads`.`id` = `ad_locations`.`ad_id`) AS `ad_locations_count`
FROM `ads`
LEFT JOIN `ad_categories` on `ad_categories`.`ad_id` = `ads`.`id`
WHERE date(`expire_date`) >= '2021-04-01' AND date(`expire_date`) < '2021-05-01' AND `ad_categories`.`category_id` in ('1', '2', '3', '4', '6', '7', '8')
ORDER BY `expire_date` asc, `price` desc
I got no rows returned, but in database I see ralated rows :
Manually removing rows with ad_categories.category_id` :
SELECT `ads`.*, ( SELECT count(*)
FROM `ad_locations`
WHERE `ads`.`id` = `ad_locations`.`ad_id`) AS `ad_locations_count`
FROM `ads`
LEFT JOIN `ad_categories` on `ad_categories`.`ad_id` = `ads`.`id`
WHERE date(`expire_date`) >= '2021-04-01' AND date(`expire_date`) < '2021-05-01'
ORDER BY `expire_date` asc, `price` desc
I got all data I need.
What is wrong ?
Thanks!

use select...
$data = Ad
::whereDate('expire_date', '>=', $date_start)
->whereDate('expire_date', '<', $date_end)
->orderBy($order_by, $order_direction)
->with('adCategories')
->with('creator')
->withCount('adLocations')
->leftJoin('ad_categories', 'ad_categories.ad_id', '=', 'ads.id')
->whereIn('ad_categories.category_id', $adsCategories)
->select('ads.*', 'ad_categories.*') // <- add this line of code
->get();

Related

Nested Select in Eloquent

I want to recreate below SQL in Eloquent (Laravel 6 LTS)
I want to avoid DB::raw as I have logics behind the PartnerPrice::class (model)
SELECT *
FROM (SELECT *,
ROW_NUMBER ()
OVER (PARTITION BY group, TYPE
ORDER BY effective_at DESC, created_at DESC)
r
FROM partner_prices
WHERE group = 'premier'
and partner_id = 8
AND TYPE = 'premium'
AND effective_at <= '2020-10-31') a
WHERE r = 1
ORDER BY group;
Here's my working inner query.
I just need help wrapping this with another select and add a where('r', 1)
$sub = PartnerPrice::select('*')
->selectRaw('ROW_NUMBER () OVER (PARTITION BY mccmnc, TYPE ORDER BY effective_at DESC, created_at DESC) r')
->where('type', $type)
->where('partner_id', $partnerId)
->where('group', $group)
->where('effective_at', '<=', now()->subMonth()->lastOfMonth())
->get();
You could use the toSql method with mergeBindings like this
$queryBuilder = PartnerPrice::select('*')
->selectRaw('ROW_NUMBER () OVER (PARTITION BY mccmnc, TYPE ORDER BY effective_at DESC, created_at DESC) r')
->where('type', $type)
->where('partner_id', $partnerId)
->where('group', $group)
->where('effective_at', '<=', now()->subMonth()->lastOfMonth());
$result = DB::table(DB::raw('(' . $queryBuilder->toSql() . ') as a'))
->mergeBindings($queryBuilder->getQuery())
->where('a.r', 1)
->get();
Note that I omitted the get() on the first builder
Also I think you can use
DB::select('*')
->fromSub($queryBuilder, 'a')
->where('a.r', 1)
->get();
But never used it. try this too.

subquery inside orWhere in laravel

I need assistance to build up the query like below in laravel:
SELECT *
FROM table t
WHERE t.a = 1
OR (t.a=0
AND t.id IN (
SELECT o.a_id
FROM other_table o
WHERE o.x > 3
)
);
You could try to build your exact current query, and in fact it might even be the most efficient to write it. But, if we rephrase your query using a left join, it becomes somewhat easier to express in Laravel code.
SELECT *
FROM your_table t
LEFT JOIN other_table o
ON t.id = o.a_id AND o.x > 3
WHERE
t.a = 1 OR
(t.a = 0 AND o.a_id IS NOT NULL);
This would translate to the following Laravel code:
$result = DB::table('your_table t')
->leftJoin('other_table o', function($join) {
$join->on('t.id', '=', 'o.a_id');
$join->on('o.x', '>', '3');
})
->where('t.a', '=', '1')
->orWhere(function($query) {
return $query->where('t.a', '=', '0')
->whereNotNull('o.a_id')
})
->get();

how to create select join multiple condition in laravel 5.3

how to create select join multiple condition in laravel 5.3
SQL SELECT Statement.
SELECT table_1.column_1
,table_2.column_1
,table_3.column_1
FROM table_1
LEFT JOIN table_2
ON table_1.column_1 = table_2.column_1
LEFT JOIN table_3
ON table_1.column_2 = table_3.column_2
AND table_3.column_3 <= NOW()
AND ( table_3.column_4 >= NOW()
OR table_3.column_4 = 0
)
WHERE table_1.column_1 = '0000000001'
I want to convert SQL Statement to laravel select.
I try.
$result = DB::table('table_1')
->select('table_1.column_1', 'table_2.column_1', 'table_3.column_1')
->leftJoin('table_1', 'table_1.column_1', '=', 'table_2.column_1')
->leftJoin('table_3', 'table_1.column_2', '=', 'table_3.column_2')
->where('table_1', $_POST['id'])
->get();
DB::table('table_1')
->select('table_1.column_1', 'table_2.column_1', 'table_3.column_1')
->leftJoin('table_1', 'table_1.column_1', '=', 'table_2.column_1')
->leftJoin('table_3', 'table_1.column_2', '=', 'table_3.column_2')
->where('table_1.column_1', $_POST['id'])
->where('table_3.column_3','>=', NOW())
->where(function($query) {
$query->where('table_3.column_4', '>=', NOW())
->orWhere('table_3.column_4','0');
})
->get();

Lumen eloquent left join

I want to make some migration from Laravel to Lumen, before that every code on my Laravel working and has no error and running well. Then i found this line and eloquent in Lumen translate this different than Laravel.
DB::table('products_categories')
->select('products.*', 'brands.name as brand_name', 'categories.link_rewrite as category_link_rewrite',
'product_medias.id as id_image', 'product_stocks.quantity as product_stock', 'product_medias.path','product_medias.filename', 'specific_prices.reduction_type', 'specific_prices.reduction as reduction',
'specific_prices.reduction', 'products_categories.position')
->leftJoin('products', 'products.id', '=', 'products_categories.product_id')
->leftJoin('product_stocks', 'products.id', '=', 'product_stocks.product_id')
->leftJoin('brands', 'brands.id', '=', 'products.brand_id')
->leftjoin('product_medias', function($join){
$join->on('product_medias.product_id', '=', 'products.id')
->whereIn('product_medias.cover', [1, 0]);
})
->leftJoin('categories', 'products_categories.category_id', '=', 'categories.id')
->leftJoin('specific_prices', function($join){
$join->on('specific_prices.product_id', '=', 'products.id')
->on(DB::raw("(`specific_prices`.`from` = '0000-00-00 00:00:00' OR '".date('Y-m-d H:i:s')."' >= `specific_prices`.`from`)"), DB::raw(''), DB::raw(''));
})
->where('categories.name','=', "Special Price" )
->where('products.active','=', 1)
->whereNull('products.deleted_at')
->groupBy('products_categories.product_id')
->orderBy('products_categories.id', 'desc');
Once again it's working on my Laravel but i get 'Error' on Lumen, is there any solution to solve this?
If i dump this line the query will look like this :
select `products`.*, `brands`.`name` as `brand_name`, `categories`.`link_rewrite` as `category_link_rewrite`, `product_medias`.`id` as `id_image`, `product_stocks`.`quantity` as `product_stock`, `product_medias`.`path`, `product_medias`.`filename`, `specific_prices`.`reduction_type`, `specific_prices`.`reduction` as `reduction`, `specific_prices`.`reduction`, `products_categories`.`position` from `products_categories` left join `products` on `products`.`id` = `products_categories`.`product_id` left join `product_stocks` on `products`.`id` = `product_stocks`.`product_id` left join `brands` on `brands`.`id` = `products`.`brand_id` left join `product_medias` on `product_medias`.`product_id` = `products`.`id` and `product_medias`.`cover` in (1, 0) left join `categories` on `products_categories`.`category_id` = `categories`.`id` left join `specific_prices` on `specific_prices`.`product_id` = `products`.`id` and (`specific_prices`.`from` = '0000-00-00 00:00:00' OR '2016-11-14 09:12:44' >= `specific_prices`.`from`) = where `categories`.`name` = Special Price and `products`.`active` = 1 and `products`.`deleted_at` is null group by `products_categories`.`product_id` order by `products_categories`.`id` desc limit 10
There is equal symbol after left join specific_prices and also didn't track 'Special Price' as character

Query builder isn't execute where = on another column

Sorry, my question title isn't very clear but I couldn't figure a way to word this question.
I have the following query builder code.
return self::select(DB::raw('sum(user_points.points) AS points, users.id AS user_id, users.username, users.avatar, users.firstname, users.lastname'))
->join('users', 'users.id', '=', 'user_points.user_id')
$query->where('user_points.artist_id', 0)->orWhere('user_points.artist_id', 'users.favourite_artist_id');
})
->where('user_points.created_at', '>=', $startDate)
->where('user_points.created_at', '<=', $endDate)
->groupBy('users.id')
->orderBy('points', 'DESC')
->orderBy('user_id', 'ASC')
->simplePaginate(100);
It runs ok but is ignore the inner where query, specifically it's ignoring part of this;
$query->where('user_points.artist_id', 0)->orWhere('user_points.artist_id', 'users.favourite_artist_id');
})
It's matching 'user_points.artist_id = 0', but it's not matching the 'user_points.artist_id = users.favourite_artist_id', presumable it's got something to do with the way it's handling the bindings? But I can't seem to find a way to get it to work.
The complete query should end up like this;
SELECT SUM(user_points.points) AS points, users.id AS user_id, users.username, users.avatar, users.firstname, users.lastname
FROM user_points
INNER JOIN users ON users.id = user_points.user_id
WHERE (user_points.artist_id = 0 OR user_points.artist_id = users.favourite_artist_id)
AND user_points.created_at >= '$startDate' AND user_points.created_at <= '$endDate'
GROUP BY user_id
ORDER BY points DESC, user_id ASC
I updated the query builder code to this.
return self::select(DB::raw('sum(user_points.points) AS points, users.id AS user_id, users.username, users.avatar, users.firstname, users.lastname'))
->join('users', 'users.id', '=', 'user_points.user_id')
->where(function($query) {
$query->Where('user_points.artist_id', 0)->orWhere(DB::raw('user_points.artist_id = users.favourite_artist_id'));
})
->where('user_points.created_at', '>=', $startDate)
->where('user_points.created_at', '<=', $endDate)
->groupBy('users.id')
->orderBy('points', 'DESC')
->orderBy('user_id', 'ASC')
->simplePaginate(100);
That didn't work as the final query ended up looking like this.
select sum(user_points.points) AS points, users.id AS user_id, users.username, users.avatar, users.firstname, users.lastname
from `user_points` inner join `users` on `users`.`id` = `user_points`.`user_id` where (`user_points`.`artist_id` = ? or user_points.artist_id = users.favourite_artist_id is null)
and `user_points`.`created_at` >= ?
and `user_points`.`created_at` <= ?
group by `users`.`id`
order by `points` desc, `user_id` asc
You need to add the second where (or) as a raw query. The where method will add the second column as a value so you are actually trying the following:
user_points.artist_id = 'users.favourite_artist_id'
Try the following:
whereRaw("user_points.artist_id = users.favourite_artist_id")

Resources