Not able to fetch data from primary table in laravel - php

I have 3 tables i.e category, sub category and products. I have passed category id to sub category and then sub category id to product so that i can get the whole data as per requirements. The problem in i an able to get the data from the secondary tables that has joins statement not from the primary table.Here is my code of query. Any help from you would be appreciated
public function showProduct()
{
$data = DB::table('category')
->join('sub_category','category.id',"=",'sub_category.category_id')
->join('product','sub_category.id', '=', 'product.sub_category_id')
->get();
return $this->success('date' ,$data);
}

use leftjoin
$data = DB::table('category')
->leftjoin('sub_category','category.id',"=",'sub_category.category_id')
->leftjoin('product','sub_category.id', '=', 'product.sub_category_id')
->get();

Related

Cant join tables in laravel

I am new to laravel.
I need to join two tables, and i dont know what i am doing wrong.
When i check at telescope, my query isnt displayed.
This is the query i want to run
SELECT * FROM products join subcategories on products.subcategories_id = subcategories.id where subcategories.categories_id = 1
In my laravel controller i have
public function showCategoriesProducts(String $cat){
$categories = Categories::all();
$products = Products::join('subcategories', function($join) {
$join->on('products.subcategories_id', '=', 'subcategories.id');
}) ;
dd($products);
return view('products.index',compact('products','categories'));
}
This is my web.php
Route::get('/categories/{categories_id}', 'ProductController#showCategoriesProducts')->name('categories.show');
My Products belong to subcategories and subcategories belong to Categories. I need to fetch products from category id.
Please Help
Thank You!
You are building the query, but not fetching records. Add ->get() add the end of your query to make the request.
$products = Products::join('subcategories', function($join) {
$join->on('products.subcategories_id', '=', 'subcategories.id');
})->get();

In Laravel my table columns overwrite with join, how can i solve?

I have a mini problem in my application... I want to get all products from the products table along with the category name from the categories table and get stock of each product from products_attribute table... the problem is product table id overwrite with products_attribute id. In the product_attributes table, only 116 rows but products table has 177 rows and the loop gets only 116 rows with products_attribute id.
Product Table (Screenshot)
Product Attributes Table (Screenshot)
Categories Table (Screenshot)
public function viewProducts(Request $request)
{
$products = Product::join('categories', 'categories.id', 'products.category_id')->join('products_attributes', 'products_attributes.product_id', 'products.id')->get();
$products = json_decode(json_encode($products));
return view('admin.products.view_products')->with(compact('products'));
}
Laravels join function default is inner join so You will need to use the leftJoin method. (See \vendor\laravel\framework\src\Illuminate\Database\Query\Builder#join)
I hope It will be helpful.. How to use left join:
$products = Product::join('categories', 'categories.id', 'products.category_id')->leftjoin('products_attributes', 'products_attributes.product_id', 'products.id')->get();
You have to use aliases to preserve columns from the base table that will be overwritten by your joining table(s):
$products = Product::select('*', \DB::raw("product.id as product_id"))->join('categories', 'categories.id', '=', 'product.id')->get();
You can then access the product id using: $product->product_id

Laravel join two tables for ruled out records

In Laravel, how can I reject a record in a query based on a value with one of the table with which this table has relations?
For example, I have the Products table and the Categories table. The Categories table has a one-to-many relationship, one category can have many products. The categories table are is_visible is_deleted. How to make inquiries on the Products table so that it rejects products that belong to the category that has and set fields is_visible = false or is_deleted = true ?
I tried something like this:
$products = ProductTable::join('product_category_tables', 'product_category_tables.id', '=', 'product_tables.id')
->where('product_category_tables.is_visible', '=', true)
->where('product_category_tables.is_deleted', '=', false)
->where('product_tables.is_visible', '=', true)
->where('product_tables.is_deleted', '=', false)
->paginate(50);
But from this query I have only one record. I can't make this query on Category table becouse I want get only 25/50/100 products for paginate.
If you are using Laravel Modal(Eloquent) and have defined the one to many relationship properly in both Product and Category Model. then you can achieve this by the following query:
$products = Product::where("is_visible", true)
->where("is_deleted", false)
->whereHas('category', function($categories){
$categories->where("is_visible", true)
->where("is_deleted", false);
})
->get();
In Product model you should have defined the relationship as bellow:
public function category()
{
//From your mentioned query I am seeing that
//product table's id is actually categories table's id(which should not be like this though),
//so the relationship is
return $this->belongsTo(Category::class, 'id');
}

Laravel Group By relationship column

I have Invoice_Detail model which handles all products and it's quantities, this model table invoice_details has item_id and qty columns.
The Invoice_Detail has a relation to Items model which holds all item's data there in its items table, which has item_id, name, category_id.
The Item model also has a relation to Category model which has all categories data in its categories table.
Question: I want to select top five categories from Invoice_Detail, how?
Here's what I did:
$topCategories = InvoiceDetail::selectRaw('SUM(qty) as qty')
->with(['item.category' => function($query){
$query->groupBy('id');
}])
->orderBy('qty', 'DESC')
->take(5)->get();
But didn't work !!
[{"qty":"11043","item":null}]
Category::select('categories.*',\DB::raw('sum("invoice_details"."qty") as "qty"'))
->leftJoin('items', 'items.category_id', '=', 'categories.id')
->leftJoin('invoice_details', 'invoice_details.item_id', '=', 'items.id')
->groupBy('categories.id')
->orderBy('qty','DESC')
->limit(5)
->get();
This will return you collection of top categories.
Tested on laravel 5.5 and PostgreSQL.
UPD:
To solve this without joins you can add to Categories model this:
public function invoiceDetails()
{
return $this->hasManyThrough(Invoice_Detail::class, Item::class);
}
And to select top 5 categories:
$top = Category::select()->with('invoiceDetails')
->get()->sortByDesc(function($item){
$item->invoiceDetails->sum('qty');
})->top(5);
But first solution with joins will work faster.

Combining relationship sorting and filtering

I have two models: Item and Category. The Item model has a category_id field which is a foreign key of the category.
On the search page I am currently performing filtering. This is done via a series of where() clauses, for example
if($request->input('location_id', "") != "") {
$query->where('location_id', '=', $request->input('location_id'));
}
These are contained within the scope search(), so they are called like this:
$results = Item::search($request)->get();
I now want to apply sorting to the results, firstly by the name column of the category, then by the product_number column on the items table.
How would I go about doing this without interfering with the filtering in the search scope?
Just add multiple calls to orderBy():
$results = Item::search($request)
->join('categories', 'category_id', '=', 'categories.id')
->select('items.*')
->orderBy('categories.name')
->orderBy('product_number')
->get();

Categories