Column not found in laravel - sql

I'm trying to create a self join in laravel using aliases, but it doesn't seem to want to pick it up, because I get an error saying that the columns p1.sub_menu and p2.5 are not found. Here is my join:
$menu = DB::table('pages AS p1')
->leftJoin('pages AS p2', 'p1.sub_menu', '=', 'p2.'.$id.'')->get();

Error because of your leftJoin statement
Params in leftJoin statement are columns which you want to use relationships.
$menu = DB::table('pages AS p1')->leftJoin('pages AS p2', 'p1.sub_menu', '=', **'p2.'.$id.''**)->get();
My solution is:
$menu = DB::table('pages AS p1')->leftJoin('pages AS p2', 'p1.sub_menu', '=', 'p2.sub_menu')->where("p2.menu_id", "=", $menu_id)->get();

Related

Laravel query builder left join from subquery

I'm using Laravel query builder and trying to do something like this:
$builder = DB::table('mainTable')->where("mainTable.id", "=", 111);
$builder->leftJoinSub(
DB::table('table2')
->where('table2.id', '=', DB::raw("mainTable.subtableId"))
->where('table2.region', '=', DB::raw("mainTable.region"))
->orderBy('table2.someOrder', 'DESC')
->select('kamery2.id')
->first(),
'myId',
'table2.id',
'=',
'myId'
);
And I'm getting
The multi-part identifier "mainTable.subtableId" could not be bound.
However when I write it with DB::raw('...') it works.
$builder->leftJoin(
'table2',
'table2.id',
'=',
DB::Raw("...")
);
So I'm trying to find out what I'm doing wrong. Did I make a syntactic mistake only? Or Laravel query's builder doesn't allow what I want to achieve and I have to use ->leftJoin(.... DB::raw() ) ?

exists query does not return relevant result

I have a Laravel application with this Eloquent query:
$products = Product::where('name', 'LIKE', "%{$value}%")
->whereHas('categories', function($q) {
$q->where( 'slug', 'tonery-cartridge' );
})->with('manufacturer')
->with('sm_image')
->orderBy('created_at','DESC')
->take(10)
->get();
This code generates the sql command like:
select * from `products` where `name` LIKE '%can%'
and exists (
select * from `categories` inner join `category_product`
on `categories`.`id` = `category_product`.`category_id`
where `products`.`id` = `category_product`.`product_id`
and `slug` = 'tonery-cartridge'
)
order by `created_at` desc limit 10
I am sure there are products which name contains "can" string and which belongs to the category with slug "tonery-cartridge". Why this query returns an empty result? If I try to make inner join sql manually it works well as on the screenshot below:
I think that your queries are not equivalent. The SQL output from laravel does not join tables in it's FROM clause, but in your manually constructed SQL statement you do a lot of inner joins in your FROM clause and on the resulting table you perform your operations, which is not true for the former.
Try the following
DB::table('products')
->join('category_product', 'category_product.product_id', '=', 'products.id')
->join('categories', 'category_product.category_id', '=', 'categories.id')
->whereRaw('products.name LIKE %can% AND categories.slug = "tonery-cartridge"')
->select('products.name', 'categories.slug')
->orderBy('created_at','DESC')
->take(10)
->get()
If you want to avoid using whereRaw, you can try the following.
DB::table('products')
->join('category_product', 'category_product.product_id', '=', 'products.id')
->join('categories', 'category_product.category_id', '=', 'categories.id')
->where([
['products.name, 'LIKE', '%' . $value . '%'],
['categories.slug', '=', 'tonery-cartridge']])
->select('products.name', 'categories.slug')
->orderBy('created_at','DESC')
->take(10)
->get()
HTH
This could be one of the solutions
$category = Category::where( 'slug', 'tonery-cartridge' )->first();
$products = $category->products()
->where('name', 'LIKE', "%{$value}%")
->with('manufacturer')
->with('sm_image')
->latest()
->take(10)
->get();

fetch data using query builder by checking multiple data from same column in laravel

DB::table('products')
->where('status', '=', 'published')
->where('sub_category', '=', 'grooming-wellness')
->where('sub_category', '=', 'beauty-care')
->get();
it doesn't work. it returns 0 data.
I am assuming you want to check if a field has a particular value or another value. You can use whereIn to achieve this:
DB::table('products')
->where('status', '=', 'published')
->whereIn('sub_category', ['grooming-wellness', 'beauty-care'])
->get();
Laravel 6.x Docs - Query Builder - Where Clauses - Additional Where Clauses whereIn

ambiguous in property names of object due to inner join in laravel

I using following code for joining two tables in my controller
$clientdata = DB::table('clients')
->join('users', 'clients.id', '=', 'users.id')->get();
In blade:
#foreach($clientdata as $clientdata)
<td>{{$clientdata->first_name(client)}}</td>
<td>{{$clientdata->last_name(client)}}</td>
<td>{{$clientdata->first_name(users)}}</td>
<td>{{$clientdata->last_name(users)}}</td>
#endforeach
but my both tables clients and users contains column of same name as first_name and last_name, and i want to access first_name and last_name of both clients table and users table, so how can i do that
You can do
$clientdata = DB::table('clients')
->join('users', 'clients.id', '=', 'users.id')
->select(
'users.first_name as users_first_name',
'users.last_name as users_last_name',
'clients.first_name as clients_first_name',
'clients.last_name as clients_last_name',
)
->get();
In your blade file:
#foreach($clientdata as $data)
<td>{{$data->users_first_name}}</td>
<td>{{$data->users_last_name}}</td>
<td>{{$data->clients_first_name}}</td>
<td>{{$data->clients_last_name}}</td>
#endforeach
I use always this solution
Lazy one :) (In case of high number of columns)
I select all columns in both tables (table.*), and I add my ambiguous columns with aliases (table.ambiguous_1 AS alias)
Example
$clientdata = DB::table('clients')
->join('users', 'clients.id', '=', 'users.id')
->select(
'users.*',
'clients.*',
'users.first_name AS users_first_name',
'users.last_name AS users_last_name',
'clients.first_name AS clients_first_name',
'clients.last_name AS clients_last_name',
)
->get();
In the blade I use the alias for ambiguous columns and orginal column name in others.
Try this code
DB::table('clients') ->join('users', 'clients.id', '=', 'users.id')->select('clients*', DB::raw('clients as client_name'))->get();

How to use 'Where Not In' in Laravel 5.4?

I'm trying to create a query where I get data from a table and I use INNER JOIN and Where Not In, I was able to adapt the INNER JOIN part, but in 'WHERE NOT IN' I tried using 'WhereNotIn' from Laravel 5.4. But it returns the error: Invalid argument supplied for foreach()
SELECT
em.erp_mlbid AS category_id
FROM
erp_product AS ep
INNER JOIN
erp_product_category AS epc ON epc.erp_productid = ep.erp_productid
INNER JOIN
erp_mlbcategory_erpcategory AS emc ON emc.erp_categoryid = epc.erp_categoryid
INNER JOIN
erp_mlb_category AS em ON em.erp_mcid = emc.erp_mlbcategoryid
WHERE
ep.erp_productid NOT IN (
SELECT
epm.erp_productid
FROM
erp_product_to_mlb AS epm
)
AND ep.erp_quantity > 0
AND ep.erp_status > 0
LIMIT
10,10
So I created this in my application:
$categoria = DB::table('erp_product')
->join('erp_product_category','erp_product_category.erp_productid', '=', 'erp_product.erp_productid')
->join('erp_mlbcategory_erpcategory', 'erp_mlbcategory_erpcategory.erp_categoryid', '=','erp_product_category.erp_categoryid')
->join('erp_mlb_category', 'erp_mlb_category.erp_mcid', '=', 'erp_mlbcategory_erpcategory.erp_mlbcategoryid')
->select('erp_mlb_category.erp_mlbid')
->whereNotIn('erp_product.erp_productid', function($query){
$query->select('erp_productid')
->from('erp_product')
->where('erp_productid', '=', 'erp_product_category.erp_productid');
})
->get();
Any suggestion?
This lines of code is wrong:
->whereNotIn('erp_product.erp_productid', function($query){
$query->select('erp_productid')
->from('erp_product')
->where('erp_productid', '=', 'erp_product_category.erp_productid');
})
remove this line ->where('erp_productid', '=', 'erp_product_category.erp_productid') cause there is not join here.
you can't say ->whereNotIn('erp_product.erp_productid' and $query->select('erp_productid')->from('erp_product') in the same order whereNotIn to check the value in the first_column not exists in the second_column not in same first_column.
So, clear this line ->where('erp_productid', '=', 'erp_product_category.erp_productid') and check the right name to put in $query->select('right_column_name')->from('right_table_name').
$ids= DB::table('erp_product')->pluck('erp_productid')
$categoria = DB::table('erp_product')
->join('erp_product_category','erp_product_category.erp_productid', '=', 'erp_product.erp_productid')
->join('erp_mlbcategory_erpcategory', 'erp_mlbcategory_erpcategory.erp_categoryid', '=','erp_product_category.erp_categoryid')
->join('erp_mlb_category', 'erp_mlb_category.erp_mcid', '=', 'erp_mlbcategory_erpcategory.erp_mlbcategoryid')
->select('erp_mlb_category.erp_mlbid')
->whereNotIn('erp_product.erp_productid',$ids)
->get();