Nested query in laravel 5.5 - php

I want to get my products info from AppServiceProvider
Logic
Category -> Subcategory -> Product
now I need to get products base on category id
note: you might think it's strange but it's not really, just imagine you want show products in category page from all subcategories of that category. Then you'll need such thing like i do. getting products base on category_id while you only save subcategory_id in products table.
this is my loop in AppServiceProdiver:
View::composer('welcome', function ($view) {
$categories = Category::join('admin_designs', 'admin_designs.category_id', '=', 'categories.id')->get();
foreach($categories as $category){
$subcategory = Subcategory::join('categories', 'categories.id', '=', 'subcategories.category_id')->first();
$designs = Product::where('subcategory_id', $subcategory)->first();
}
$view->with('categories', $categories);
});
result of that loop is:
{"id":2,"title":null,"slug":"laptop","image":"category-1516430091.jpg","imageAlt":null,"status_id":1,"meta_tags":"laptop,tags","meta_description":"laptop description","created_at":"2018-02-01 11:41:30","updated_at":"2018-02-01 11:41:30","category_id":1},
PS: have no idea what is that! is not product/ is not complete
category less title!... :|
anyone can help with fixing that query?

SOLVED
View::composer('welcome', function ($view) {
$category = DB::table('admin_designs')
->join('categories', 'categories.id', '=', 'admin_designs.category_id')
->join('subcategories', 'subcategories.category_id', '=', 'categories.id')
->join('products', 'products.subcategory_id', '=', 'subcategories.id')
->get();
$view->with('category', $category);
});
Hope it helps.

Related

Display best selling items by status

Explaining my problem, I have two tables in my database called order and order_details.
On my dashboard, I display the three best-selling items (currently work!). However, I would like to display only the best selling items THAT have the status = delivered.
Today, it works like this:
$top_sell_items = OrderDetails::with(['product'])
->select('product_id', DB::raw('SUM(quantity) as count'))
->groupBy('product_id')
->orderBy("count", 'desc')
->take(3)
->get();
The problem is that the order status is stored in another table, called orders, column order_status.
How can I create this rule and include it in my $top_sell_items?
if you relationship is done between this table already, you can use this code, if not you have to go to the OrderDetails Model and add new method orders
$top_sell_items = OrderDetails::with(['product', 'orders'])
->whereHas('orders', function($query) {
$query->where('status', 'delivered');
})
->select('product_id', DB::raw('SUM(quantity) as count'))
->groupBy('product_id')
->orderBy('count', 'desc')
->take(3)
->get();
You could either define a relationship between Orders and OrderDetails or use a join like so...
<?php
$top_sell_items = OrderDetails::with(['product'])
->join('orders', 'orders.id', '=', 'order_details.order_id')
->select('product_id', DB::raw('SUM(quantity) as count'))
->where('orders.order_status', 'delivered');
->groupBy('product_id')
->orderBy("count", 'desc')
->take(3)
->get();
More info here: https://laravel.com/docs/8.x/queries#joins
Depending if you desire this, the following solution might be the most efficient:
$products = Product
::whereHas('orderDetails.order', function ($query) {
$query->where('orders.order_status', 'delivered');
})
->withSum('orderDetails', 'quantity')
->orderBy('order_details_sum_quantity', 'desc')
->take(3)
->get();
It will directly return instances of Product. In addition it puts everything in a single query instead of the two that with produces.

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();

select option search in laravel

Please I need help, I have 2 select options fields of categories and states and a city input field. I will like to perform a search if category is only selected or if category and state is selected or if category, state and city is selected or if category and city is selected. I am using laravel framework for my project.
public function searchVendor (Request $request) {
$vendors = DB::table('vendors')
->join('categories', 'categories.id', '=', 'vendors.vendor_category_id')
->join('countries', 'countries.id', '=', 'vendors.country_id')
->join('states', 'states.id', '=', 'vendors.state_id')
->join('cities', 'cities.id', '=', 'vendors.city_id')
->select('vendors.*', 'categories.name as category_name', 'countries.name as country_name', 'states.name as state_name', 'cities.name as city_name')
->where([['vendors.vendor_category_id',$request->cid],['vendors.state_id',$request->state],['cities.name','LIKE',"%$request->location%"]])
->orderBy('vendors.featured', 'asc')
->paginate(21);
$venues = Menu::where('parent',8)->get();
$states = State::all();
return view('pages.search')->withVenues($venues)->withVendors($vendors)->withStates($states);
}
That is my search controller so far, but is not giving me what I want. Please help

Eloquent wherein with join multiple tables

I have 4 tables, items, listings, catitem_item, and item_listing.
items and listing is many to many relationship.
items and catitems is also many to many relationship.
catitems contains list of item's categories.
listings is like location where items located.
example listing shop A can have item chair and item chair have multiple catitem categories.
My goal is to get items which under list of categories such as category 1 AND 2 AND 3 ($cats) and with listing information where this item located.
So if there are 6 listings for chair, it will return 6 chair results.
This is the query I have so far.
$items = DB::table('items')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->join('item_listing', 'item_listing.item_id', '=', 'items.id')
->join('listings', 'item_listing.listing_id', '=', 'listings.id')
->whereIn('catitem_item.catitem_id', $cats)
//->groupBy('items.id')
//->having(DB::raw('count(*)'), '=', count($cats))
->select('items.id', 'items.name', 'items.price', 'items.slug', 'item_listing.listing_id', 'listings.name as listing_name', 'listings.slug as listing_slug')
->get();
Note that the way you are trying to do it, you might get multiple rows per item (once per related listing). A better way would be to have an array of listings per item.
If you use eloquent models and you have setup the relations correctly, you could try the following:
$cats = [1, 2, 3];
$query = Item::with('listings');
foreach ($cats as $cat) {
$query->whereHas('catitems', function($q) use($cat) {
$q->where('id', $cat);
});
}
$items = $query->get();
Now every item shoud have a listings property. For example for the first item you can access the listings the following way:
$item1 = $items[0];
$listings1 = $item1->listings;
Note that whereHas() will probably create a correlated EXISTS subquery for every entry in the $cats array. If that is to slow, you can use a JOIN query like:
$items = Item::with('listings')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->whereIn('catitem_item.catitem_id', $cats)
->groupBy('items.id')
->having(DB::raw('count(*)'), '=', count($cats))
->select('items.*')
->get();
If you don't use eloquent, you can also do the "eager loading" yourself.
$items = DB::table('items')
->join('catitem_item', 'catitem_item.item_id', '=', 'items.id')
->whereIn('catitem_item.catitem_id', $cats)
->groupBy('items.id')
->having(DB::raw('count(*)'), '=', count($cats))
->select('items.*')
->get()
->keyBy('id');
foreach ($items as $item) {
$item->listings = [];
}
$itemIds = $items->pluck('id');
$listings = DB::table('listings')
->join('item_listing', 'item_listing.listing_id', '=', 'listings.id')
->whereIn('item_listing.item_id', $itemIds)
->groupBy('listings.id')
->select('listings.*', DB::raw('group_concat(item_listing.item_id) as item_ids'))
->get();
foreach ($listings as $listing) {
$itemIds = explode(',', $listing->item_ids);
foreach ($itemIds as $itemId) {
$items[$itemId]->listings[] = $listing;
}
$listing->forget('item_ids');
}

selecting all fields from secondary table in eloquent

Is there any reason why my query doesn't end?, I try to get all the values from the secondary table in a join in eloquent:
Product::leftJoin('brands', 'products.brand_id', '=', 'brands.id')
->leftJoin('product_categories', function($query) use ($parent){
$query->on('products.category_id', '=', 'product_categories.id')
->where('product_categories.parent_id', $parent);
})
->selectRaw('brands.*')
->groupBy('brands.id')
->get();
If I select products.* the query goes fine, but with brands.* it never ends, Does someone knows what is happening?
If i run the sql directly in phpmyadmin, it gives me the result.
What i need with this query is to get all brands with existing products that its category has parent_id = $parent
Well i don't know why eloquent has a problem with getting the fields from the second table, but I used query builder so this query work. I leave my "solution", maybe it is useful to someone:
$brands = Product::leftJoin('brands', 'products.brand_id', '=', 'brands.id')
->leftJoin('product_categories', function($query) use ($parent){
$query->on('products.category_id', '=', 'product_categories.id')
->where('product_categories.parent_id', $parent);
})
->selectRaw('brands.*')
->groupBy('brands.id');
$bindings = $brands->getBindings();
$sql = $brands->toSql();
$sql = vsprintf(str_replace('?', '%s', $sql), $bindings);
$brands = \DB::select($sql);

Categories