Laravel 5.3 Join on Field Value - laravel

This Laravel Model Query
PostModel::select('posts.*', 'users.name', 'users.user_fullname', 'users.user_gender', 'users.user_picture', 'users.user_picture_id', 'users.user_cover','users.user_cover_id', 'users.user_verified', 'users.user_pinned_post', 'pages.*', 'groups.group_name', 'groups.group_picture_id', 'groups.group_cover_id', 'groups.group_title', 'groups.group_admin', 'groups.group_pinned_post')
->leftjoin('users',function($flj){
$flj->on('posts.user_id', '=' ,'users.id')
->where('posts.user_type','=','user');
})
->leftjoin('pages',function ($slj){
$slj->on('posts.user_id', '=', 'pages.page_id')
->where('posts.user_type','=','page');
})
->leftjoin('groups',function ($tlj){
$tlj->on('posts.in_group','=',1)
->whereColumn('posts.group_id', '=', 'groups.group_id');
})
->whereRaw('NOT (users.name <=> NULL AND pages.page_name <=> NULL)')
->where('posts.post_id','=',$id)->get();
When Query Run Then Give me this Error
SQLSTATE[42S22]: Column not found: 1054 Unknown column '1' in 'on clause' (SQL: select `posts`.*, `users`.`name`, `users`.`user_fullname`, `users`.`user_gender`, `users`.`user_picture`, `users`.`user_picture_id`, `users`.`user_cover`, `users`.`user_cover_id`, `users`.`user_verified`, `users`.`user_pinned_post`, `pages`.*, `groups`.`group_name`, `groups`.`group_picture_id`, `groups`.`group_cover_id`, `groups`.`group_title`, `groups`.`group_admin`, `groups`.`group_pinned_post` from `posts` left join `users` on `posts`.`user_id` = `users`.`id` and `posts`.`user_type` = user left join `pages` on `posts`.`user_id` = `pages`.`page_id` and `posts`.`user_type` = page left join `groups` on `posts`.`in_group` = `1` and `posts`.`group_id` = `groups`.`group_id` where NOT (users.name <=> NULL AND pages.page_name <=> NULL) and `posts`.`post_id` = 360)
If i run this query direct on database no error
Query is
select `posts`.*, `users`.`name`, `users`.`user_fullname`, `users`.`user_gender`, `users`.`user_picture`, `users`.`user_picture_id`, `users`.`user_cover`, `users`.`user_cover_id`, `users`.`user_verified`, `users`.`user_pinned_post`, `pages`.*, `groups`.`group_name`, `groups`.`group_picture_id`, `groups`.`group_cover_id`, `groups`.`group_title`, `groups`.`group_admin`, `groups`.`group_pinned_post` from `posts` left join `users` on `posts`.`user_id` = `users`.`id` and `posts`.`user_type` = 'user' left join `pages` on `posts`.`user_id` = `pages`.`page_id` and `posts`.`user_type` = 'page' left join `groups` on `posts`.`in_group` = 1 and `posts`.`group_id` = `groups`.`group_id` where NOT (users.name <=> NULL AND pages.page_name <=> NULL) and `posts`.`post_id` = 360
And how to use where not in laravel??
Thanks's

You can replace
->whereRaw('NOT (users.name <=> NULL AND pages.page_name <=> NULL)')
with
->whereNotNull('users.name')
->whereNotNull('pages.page_name')
Edit:
Replace this
->leftjoin('groups',function ($tlj){
$tlj->on('posts.in_group','=',1)
->whereColumn('posts.group_id', '=', 'groups.group_id');
with
->leftjoin('groups',function ($tlj){
$tlj->on('posts.group_id','=', 'groups.group_id');
And put the in_group before your ->whereNotNull()
->where('posts.in_group', '=', 1)

Related

Laravel Query Builder: Using `Case` with `Joins`

I am trying to replicate the following psql query in laravel:
SELECT
DISTINCT
I.id,
T.id,
T.name,
I.first_name,
I.middle_name,
I.last_name,
I.dob,
CASE WHEN NOT E.email IS NULL THEN '<<' ELSE '' END
FROM individuals AS I
LEFT JOIN titles AS T ON I.title_id = T.ID
LEFT JOIN individuals_emails_map AS IEM ON IEM.individual_id = I.id
LEFT JOIN emails AS E ON E.id = IEM.email_id;
When I use the query builder and write:
DB::table('individuals AS I')
->join('titles AS T', 'T.id', '=', 'I.title_id')
->leftjoin('individuals_emails_map AS IEM', 'IEM.individual_id', '=', 'I.id')
->leftjoin('emails AS E', 'E.id', '=', 'IEM.email_id')
->distinct('I.title_id', 'T.name', 'I.first_name', 'I.middle_name', 'I.last_name', 'I.dob')
->select('T.id','T.name', 'I.first_name','I.middle_name','I.last_name','I.dob')
->get();
... it works fine, however when I try and insert the CASE line:
DB::table('individuals AS I')
->join('titles AS T', 'T.id', '=', 'I.title_id')
->leftjoin('individuals_emails_map AS IEM', 'IEM.individual_id', '=', 'I.id')
->leftjoin('emails AS E', 'E.id', '=', 'IEM.email_id')
->distinct('I.title_id', 'T.name', 'I.first_name', 'I.middle_name', 'I.last_name', 'I.dob')
->select('T.id','T.name', 'I.first_name','I.middle_name','I.last_name','I.dob',
DB::raw("CASE WHEN NOT E.email IS NULL THEN '<<' ELSE '' END"))
->get();
... I get the following error:
Undefined table: 7 ERROR: missing FROM-clause entry for table "e"
What am I doing wrong?
I think that the problem in your case statement:
DB::raw("CASE WHEN NOT E.email IS NULL THEN '<<' ELSE '' END"))
it should be:
DB::raw('case WHEN E.email is Not NULL THEN "<<" Else " " END resultEmail'))

Laravel having query

This is my query:
Order::query()
->join('dispatcher_contractor_pays', function ($join) {
$join->on('orders.id', '=', 'dispatcher_contractor_pays.order_id')
->where('dispatcher_contractor_pays.contractor_type', '=', Contractor::class);
})
->join('order_workers_value_added', function ($join) {
$join->on('orders.id', '=', 'order_workers_value_added.order_id')
->where('order_workers_value_added.worker_type', '=', Contractor::class);
})
->having('orders.amount', '>', DB::raw('SUM(order_workers_value_added.amount)
+ SUM(dispatcher_contractor_pays.sum)'));
And get error:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column 'orders.amount' in 'having clause' (SQL: select count(*) as aggregate from `orders` inner join `dispatcher_contractor_pays` on `orders`.`id` = `dispatcher_contractor_pays`.`order_id` and `dispatcher_contractor_pays`.`contractor_type` = Modules\Dispatcher\Entities\Directories\Contractor inner join `order_workers_value_added` on `orders`.`id` = `order_workers_value_added`.`order_id` and `order_workers_value_added`.`worker_type` = Modules\Dispatcher\Entities\Directories\Contractor where `status` not in (open) and `orders`.`contractor_id` = 13 and `domain_id` = 1 and exists (select * from `dispatcher_contractors` inner join `order_workers` on `dispatcher_contractors`.`id` = `order_workers`.`worker_id` where `orders`.`id` = `order_workers`.`order_id` and `order_workers`.`worker_type` = Modules\Dispatcher\Entities\Directories\Contractor and `dispatcher_contractors`.`deleted_at` is null) and `orders`.`deleted_at` is null having `orders`.`amount` > SUM(order_workers_value_added.amount) + SUM(dispatcher_contractor_pays.sum))"
What am I doing wrong?
Tables structure
orders : |id,amount,status, e.t.c |
dispatcher_contractor_pays: |id,date,sum,order_id,contractor_type, e.t.c |
order_workers_value_added: |id,amount,order_id,worker_type,worker_id, e.t.c |

I got Unknown column error on having with count

In Laravel 6 I have a request of ads with related images count
$ads = Ad
->getByTitle($this->filter_title)
->onlyNoneInfo()
->getByStatus('A')
//->imagesCount(true)
->getUserByStatus('A')
->leftJoin('users', 'users.id', '=', 'ads.creator_id')
->orderBy($this->order_by, $this->order_direction)
->select(
'ads.*',
'users.name as creator_username',
'users.email as creator_email',
'users.phone as creator_phone'
)->addSelect(['ad_images_count' => AdImage
::selectRaw('count(*)')
->whereColumn('ad_images.ad_id', 'ads.id')
])
->offset($limit_start)
->take($ads_per_page)
->distinct()
->paginate($ads_per_page);
and I see sql request ad_images_count field:
SELECT distinct `sda_ads`.*, `sda_users`.`name` AS `creator_username`, `sda_users`.`email` AS `creator_email`, `sda_users`.`phone` AS `creator_phone`, ( SELECT count(*)
FROM `sda_ad_images`
WHERE `sda_ad_images`.`ad_id` = `sda_ads`.`id`) AS `ad_images_count`
FROM `sda_ads`
LEFT JOIN `sda_users` on `sda_users`.`id` = `sda_ads`.`creator_id`
WHERE `ad_type` <> 'I' AND `sda_ads`.`status` = 'A' AND `sda_users`.`status` = 'A'
ORDER BY `price` asc limit 4 offset 0
and it works for me with valid value in ad_images_count.
I need to set filter to show only ads with images and I added a scope in App Model :
public function scopeImagesCount($query, bool $check_images_count)
{
if ($check_images_count) {
return $query->where('ad_images_count', '>', 0);
}
return $query;
}
But if to uncoment line in the request :
//->imagesCount(true)
I got error :
MODIFIED BLOCK :
With request in which I commented ad_images_count subquery:
$ads = Ad
::getByTitle($this->filter_title)
->onlyNoneInfo()
->getByStatus('A')
->getUserByStatus('A')
->imagesCount(true)
->leftJoin('users', 'users.id', '=', 'ads.creator_id')
->orderBy($this->order_by, $this->order_direction)
->select(
'ads.*',
'users.name as creator_username',
'users.email as creator_email',
'users.phone as creator_phone'
)
/*
->addSelect(['ad_images_count' => AdImage
::selectRaw('count(*)')
->whereColumn('ad_images.ad_id', 'ads.id')
])
*/
->offset($limit_start)
->take($ads_per_page)
->distinct()
->paginate($ads_per_page);
I modified scope with logging:
public function scopeImagesCount($query, bool $check_images_count)
{
\Log::info('scopeImagesCount $check_images_count ::');
\Log::info($check_images_count);
if ($check_images_count) {
\Log::info('CHECKING ::');
return $query->select(['ad_images_count' => AdImage
::selectRaw('count(*)')
->whereColumn('ad_images.ad_id', 'ads.id')
])->where('ad_images_count', '>', 0);
}
\Log::info('SKIPPED CHECKING ::');
return $query;
}
And I see logging and Unknown column error in log file:
[2020-01-30 11:29:59] local.INFO: scopeImagesCount $check_images_count ::
[2020-01-30 11:29:59] local.INFO: 1
[2020-01-30 11:29:59] local.INFO: CHECKING ::
[2020-01-30 11:29:59] local.ERROR: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ad_images_count' in 'where clause' (SQL: select count(*) as aggregate from `sda_ads` left join `sda_users` on `sda_users`.`id` = `sda_ads`.`creator_id` where `ad_type` <> I and `sda_ads`.`status` = A and `sda_users`.`status` = A and `ad_images_count` > 0) {"exception":"[object] (Illuminate\\Database\\QueryException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ad_images_count' in 'where clause' (SQL: select count(*) as aggregate from `sda_ads` left join `sda_users` on `sda_users`.`id` = `sda_ads`.`creator_id` where `ad_type` <> I and `sda_ads`.`status` = A and `sda_users`.`status` = A and `ad_images_count` > 0) at /mnt/_work_sdb8/wwwroot/lar/ads-backend-api/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669)
In resulting sql no subquery with ad_images_count
What is wrong?
MODIFIED BLOCK # 2:
If to comment imagesCount with request
$ads = Ad
::getByTitle($this->filter_title)
->onlyNoneInfo()
->getByStatus('A')
->getUserByStatus('A')
// ->imagesCount(true)
->leftJoin('users', 'users.id', '=', 'ads.creator_id')
->orderBy($this->order_by, $this->order_direction)
->select(
'ads.*',
'users.name as creator_username',
'users.email as creator_email',
'users.phone as creator_phone'
)
->addSelect(['ad_images_count' => AdImage
::selectRaw('count(*)')
->whereColumn('ad_images.ad_id', 'ads.id')
])
->offset($limit_start)
->take($ads_per_page)
->distinct()
->paginate($ads_per_page);
I see sql generated :
SELECT distinct `sda_ads`.*, `sda_users`.`name` AS `creator_username`, `sda_users`.`email` AS `creator_email`, `sda_users`.`phone` AS `creator_phone`, ( SELECT count(*)
FROM `sda_ad_images`
WHERE `sda_ad_images`.`ad_id` = `sda_ads`.`id`) AS `ad_images_count`
FROM `sda_ads`
LEFT JOIN `sda_users` on `sda_users`.`id` = `sda_ads`.`creator_id`
WHERE `ad_type` <> 'I' AND `sda_ads`.`status` = 'A' AND `sda_users`.`status` = 'A'
ORDER BY `price` asc limit 4 offset 0
with ad_images_count field having valid value
If to uncomment imagesCount with scope:
public function scopeImagesCount($query, bool $check_images_count)
{
\Log::info('scopeImagesCount $check_images_count ::');
\Log::info($check_images_count);
if ($check_images_count) {
\Log::info('CHECKING ::');
return $query->select(['ad_images_count' => AdImage
// return $query->addSelect(['ad_images_count' => AdImage
::selectRaw('count(*)')
->whereColumn('ad_images.ad_id', 'ads.id')
])->where('ad_images_count', '>', 0);
}
\Log::info('SKIPPED CHECKING ::');
return $query;
}
I got error :
[2020-01-31 15:27:37] local.ERROR: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ad_images_count' in 'where clause' (SQL: select count(*) as aggregate from `sda_ads` left join `sda_users` on `sda_users`.`id` = `sda_ads`.`creator_id` where `ad_type` <> I and `sda_ads`.`status` = A and `sda_users`.`status` = A and `ad_images_count` > 0) {"exception":"[object] (Illuminate\\Database\\QueryException(code: 42S22): SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ad_images_count' in 'where clause' (SQL: select count(*) as aggregate from `sda_ads` left join `sda_users` on `sda_users`.`id` = `sda_ads`.`creator_id` where `ad_type` <> I and `sda_ads`.`status` = A and `sda_users`.`status` = A and `ad_images_count` > 0) at /mnt/_work_sdb8/wwwroot/lar/ads-backend-api/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669)
I tried to use addSelect - the same error.
looks like in having must subquery repeated, but not column name.
How?
MODIFIED BLOCK # 3 : 
I try to use having :
$prefix= DB::getTablePrefix();
$ads = Ad
::getByTitle($this->filter_title)
->onlyNoneInfo()
->getByStatus('A')
->getUserByStatus('A')
->leftJoin('users', 'users.id', '=', 'ads.creator_id')
->orderBy($this->order_by, $this->order_direction)
->select(
'ads.*',
'users.name as creator_username',
'users.email as creator_email',
'users.phone as creator_phone'
)
->addSelect(['ad_images_count' => AdImage
::selectRaw('count(*)')
->whereColumn('ad_images.ad_id', 'ads.id')
])
->offset($limit_start)
->take($ads_per_page)
->havingRaw(' ( SELECT count(*) '.
' FROM `'.$prefix.'ad_images'.'` '.
' WHERE '.$prefix.'ad_images.ad_id = `'.$prefix.'ads`.`id` ) > ?', [0])
->paginate($ads_per_page)
but I got error :
Unknown column 'ads-backend-api.sda_ads.id' in 'where clause' (SQL:
select count(*) as aggregate from `sda_ads` left join `sda_users` on `sda_users`.`id` = `sda_ads`.`creator_id` where `ad_type` <> I and `sda_ads`.`status` = A and `sda_users`.`status` = A having ( SELECT count(*) FROM `sda_ad_images` WHERE sda_ad_images.ad_id = `sda_ads`.`id` ) > 0
Looks like sda_ads.id is invalid condition. Which kind of wrapping does it need ?
I also tried without “`” symbol wrapping as :
->havingRaw(' ( SELECT count(*) '.
' FROM `'.$prefix.'ad_images'.'` '.
' WHERE '.$prefix.'ad_images.ad_id = '.$prefix.'ads.id ) > ?', [0])
and got :
Unknown column 'ads-backend-api.sda_ads.id' in 'where clause' (SQL: select count(*) as aggregate from `sda_ads` left join `sda_users` on `sda_users`.`id` = `sda_ads`.`creator_id` where `ad_type` <> I and `sda_ads`.`status` = A and `sda_users`.`status` = A having ( SELECT count(*) FROM `sda_ad_images` WHERE sda_ad_images.ad_id = sda_ads.id ) > 0
In my database ads-backend-api I have sda_ads table with id field.
“sda_” is db prefix in database configuration.
Which way is right ?
Thanks!
In your scope you are directly requesting 'ad_image_count' alais but you have to make alias first like you did in raw query
public function scopeImagesCount($query, bool $check_images_count)
{
if ($check_images_count) {
return $query->select(['ad_images_count' => AdImage
::selectRaw('count(*)')
->whereColumn('ad_images.ad_id', 'ads.id')
])->where('ad_images.ad_images_count', '>', 0);
}
return $query;
}

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

laravel query builder from normal query

DB::select(DB::raw( 'SELECT a.bill_no, a.account_id, a.bill_date, a.amount_paid,
b.transaction_code,b.amount from bill_det a left join
(select bill_no, transaction_code, sum(amount) as amount from payment_transactions
where status = "success" group by bill_no ) b
on a.bill_no = b.bill_no where a.amount_paid != b.amount order by b.bill_no'));
this is normal query.change into laravel query?.
i tried.
$bill=DB::table('bill_det')->leftJoin('payment_transactions', 'bill_det.bill_no', '=', 'payment_transactions.bill_no')
->select('bill_det.bill_no','bill_det.account_id','bill_det.bill_date','bill_det.amount_paid',
'payment_transactions.transaction_code',DB::raw('sum(payment_transactions.amount) as amount'))
->where('payment_transactions.status','=','success')
->where('sum(payment_transactions.amount)','!=',DB::raw('bill_det.amount_paid'))
->groupBy('bill_det.bill_no')
->orderBy('bill_det.bill_no','desc');
i can't compare -> where('sum(payment_transactions.amount)','!=',DB::raw('bill_det.amount_paid'))
i used like this ->whereRaw('bill_det.amount_paid != sum(payment_transactions.amount)')
{"error":{"type":"Illuminate\Database\QueryException","message":"SQLSTATE[HY000]: General error: 1111 Invalid use of group function (SQL: select count(*) as aggregate from (select '1' as row_count from bill_det left join payment_transactions on bill_det.bill_no = payment_transactions.bill_no where payment_transactions.status = success and bill_det.amount_paid != sum(payment_transactions.amount) group by bill_det.bill_no order by bill_det.bill_no desc) count_row_table)"
DB::select(DB::raw( 'SELECT a.bill_no, a.account_id, a.bill_date, a.amount_paid,
b.transaction_code,b.amount from bill_det a left join
(select bill_no, transaction_code, sum(amount) as amount from payment_transactions
where status = "success" group by bill_no ) b
on a.bill_no = b.bill_no where a.amount_paid != b.amount order by b.bill_no'));
After converting this to laravel Query::
$query = \Illuminate\Support\Facades\DB::table('bill_det')
->select('a.bill_no', 'a.account_id', 'a.bill_date', 'a.amount_paid', 'b.transaction_code', 'b.amount')
->leftJoin(DB::raw('(select bill_no, transaction_code, sum(amount) as amount from payment_transactions
where status = "success" group by bill_no) b'), function($join) {
$join->on('a.bill_no', '=', 'b.bill_no');
})
->where('a.amount_paid','<>', 'b.amount')
->orderBy('b.bill_no')
->get();
In case you want to know how to use raw expression inside where then use this:
$query->whereRaw(DB::raw('(your expression!!)'));

Resources