So i am confused on laravel nested queries.
I am trying to prepared a search function that filters the products that is in the sales_agreement table but also if the record has financing i want it to be filtered too.
Below is my sample.
(1) Table Products
id product_name price
1 car 500k
2 jeep 200k
3 motor 100k
4 bicycle 5k
(2) Sales Agreement
id product_id price financing
1 2 500k BPI
2 1 200k MetroBank
3 3 100k
Expected Output In my query
product_id product_name
2 jeep
1 car
4 bicycle
My Query
$result = DB::table('products')
->whereNotIn('id',function($q){
$q->select('product_id')->from('sales_agreement');
})->where('product_name','LIKE','%' . $get['q'] . '%')
->select('id','product_name')
->get();
This filters all of the products that is not in the sales_agreement table. But i also want to consider the items that has a Financing record in the sales_agreement table. In that point i dont have an idea how to do it.
Any comments/suggestion/answer will be much appreciated. Thanks !
You can try where null
$result = DB::table('products')
->whereNotIn('id',function($q){
$q->select('product_id')->from('sales_agreement')
->whereNull('financing');
})->where('product_name','LIKE','%' . $get['q'] . '%')
->select('id','product_name')
->get();
If you want to exclude the products that don't have financing record you can do a left join with additional clause
$result = DB::table('products as p')
->leftJoin('sales_agreement as s', function ($query) {
$query->on('p.id', '=', 's.product_id')
->whereNull('s.financing');
})
->whereNull('s.product_id')
->where('p.product_name', 'LIKE', '%' . $get['q'] . '%')
->select('p.id', 'p.product_name')
->get();
Related
I have made a query that counts how many products are bought together, but I don't want to have the products both ways in it
Code
DB::table(DB::raw('tenant_db.sales_data as b'))
->selectRaw('a.product_id as product_id, b.product_id as bought_with, count(*) as times_bought_together')
->join(DB::raw('tenant_db.sales_data as a'), function ($join){
$join->on('a.sale_id', '=', 'b.sale_id');
$join->on('a.product_id', '!=', 'b.product_id');
})
->groupBy('a.product_id', 'b.product_id');
Output
Product_id Bought_with times_bought_together'
52 24 3
24 52 3
So I only want to have it one time not twice, is that possible (based on quantity)?
Use < rather than !=:
$join->on('a.product_id', '<', 'b.product_id');
I have a table that I want to select product_name with lowest/min price the following:
product_name | price
Cat | 12
Dog | 21
Cat | 14
Dog | 20
Fish | 10
Fish | 3
THE DESIRE Output should be
Cat | 12
Dog | 20
Fish | 3
BELOW IS MY SQL QUERY
$products = DB::table('products')
->orderBy('products.products_price', 'asc')
->groupBy('products.products_name')
->get();
When I used this script, it only shows the highest/max price, not the lowest price
You need an aggregate instead of ordering. For Laravel, that means passing in the columns along with a DB::raw:
$products = DB::table('products')
->orderBy('products.products_price', 'asc')
->groupBy('products.products_name')
->select(['product_name', DB::raw('min(price) as price')])
->get();
Edit for ID
Taking off the answer here : SQL: Group by minimum value in one field while selecting distinct rows the mysql query would be
SELECT p1.*
FROM products p1 INNER JOIN
(
SELECT product_name, MIN(price) AS as min_price
FROM products
GROUP BY product_name
) p2 ON p1.product_name = p2.product_name AND p1.price = p2.min_price
Now we have to convert it to Query Builder
$products = DB::table('products AS p1')
->join(DB::raw('(
SELECT product_name, MIN(price) AS as min_price
FROM products
GROUP BY product_name
) AS p2'),
function($join)
{
$join->on('p1.product_name', '=', 'p2.product_name');
$join->on('p1.price', '=', 'p2.min_price');
})
->get(['p1.id', 'p1.product_name', 'p1.price']);
This has not been tested, so I hope it works
Problem:
You are not defining that the price attribute should be aggregated to a minimum.
Solution:
If you want the max price you need to select the MIN() aggregation.
You can do this by using ->selectRaw('MIN(price) as max_price').
Please Note:
If you want other attributes also selected simply add them comma separated.
->selectRaw('name, MAX(price) as max_price')
#edit
Do you still use the oderBy? If not, try it with orderBy('products.products_price', 'ASC')
working with Laravel 5.6 and mysql. I have following table name as vehicles
id name number type
1 def 123 Car
2 lki 589 Van
3 loi 256 Truck
4 oiu 569 Car
5 hyy 589 Van
Now I need count number of each type columns values I do not wanna loop count. just I need count each Type and show on blade file. like this,
Car 2
Van 2
Truck 1
etc.. how can do this?
You need to simply Group By on the type column, and use Count(*) to count the number of rows:
SELECT type, COUNT(*) AS count
FROM vehicles
GROUP BY type
This should work
$vehiclesInfo = DB::table('vehicles')
->select('type', DB::raw('count(*) as total'))
->groupBy('type')
->get();
For more info on group by and count you can follow this tutorial.
Larvel queries
Just use DB facade to get count with groupby
$vehicles= DB::table('vehicles')
->select('type', DB::raw('count(*) as total'))
->groupBy('type')
->get();
I have products table with name and no_of_sell column..
I wanted to get highest 5 sold products based on no_of_sell column from products table.
how do i use it with query builder?
$propular_products = DB::table('users')
->join('products','products.auth_id','users.id')
->select('products.*')
->orderBy('products.no_of_sell', 'desc')
->where('products.status','=','1')
->paginate(5);
suppose products table:
name no_of_sell
x 6
y 9
z 10
t 23
u 3
h 11
r 5
i wanted to find
products list of 5 max no_of_sell ie, x y z t h
So if I understand it correctly in the column no_of_sell is a int. I should write it as follow :
$best_sell = DB::table('products')
->orderBy('no_of_sell', 'desc')
->limit(5)
->where('products.status','=','1')
->paginate(4)
->get();
https://laravel.com/docs/5.4/queries#retrieving-results
https://laravel.com/docs/5.4/queries#ordering-grouping-limit-and-offset
$best_sell = DB::table('products')
->select('no_of_sell')
->where('products.status','=','1')
->orderBy('no_of_sell', 'desc')
->paginate(4);
$best_sell = DB::table('products')
->select() // your selection criteria
->where('products.status','=','1')
->take(5)->get();
I am new to laravel.
I have two tables.
1) products
2) prices
-----------------------------
- products -
-----------------------------
- id_product | int (p_key) -
- name | varchar -
-----------------------------
-------------------------
- prices -
-----------------------------
- id_price | int (p_key) -
- id_product | int -
- price | int -
-----------------------------
the products table holds data about products like id, name,...
the price changes are stored in prices table where the last record is the newest price that should be displayed to users.
now I want to search through products and get the last price of each product from prices table. this is my query:
$result = DB::table('products')->leftJoin('prices', function($join) {
$join->on('products.id_product', '=', 'prices.id_product');
})->whereRaw(MY_SEARCH_FILTERS);
the above code is wrong because if a product has 4 records in prices table, then it will be repeated 4 times in $result, but only 1 record with the last price should be displayed.
Here we have 2 tables users and answers where users is left table and answers is right table which has user answers.
We wanted to left join users with answers but the join should be with the latest record or answers table.
$query = Users::select('users.id', 'users.user_name','answers.created_at as last_activity_date')
->leftJoin('answers', function($query)
{
$query->on('users.id','=','answers.user_id')
->whereRaw('answers.id IN (select MAX(a2.id) from answers as a2 join users as u2 on u2.id = a2.user_id group by u2.id)');
})
->where('users.role_type_id', Users::STUDENT_ROLE_TYPE)->get();
you can make make it easy by using Laravel Elquent:
class Product extends Model
{
public function lastPrice()
{
// optional: change id_price to created_at by add created_at to prices table
return $this->hasOne(Price::class)->orderBy('id_price', 'DESC');
}
}
now in
public function getProducts(){
$MY_SEARCH_FILTERS=....;
// get all products with last price
$products=Product::with('lastPrice')->whereRaw(MY_SEARCH_FILTERS)->get()
return $products
}
Here we have 2 tables 'articles' and 'comments' where articles is left table and comments is right table which has article's comments.
We wanted to left join articles with comments but the join should be with the latest record from comments table.
$query = Article::select('articles.*', 'comments.comment as article_comment')
->leftJoin('comments', function($query) {
$query->on('comments.article_id','=','articles.id')
->whereRaw('comments.id IN (select MAX(a2.id) from comments as a2 join articles as u2 on u2.id = a2.article_id group by u2.id)');
})
->get();
i found this solution from here https://laravelcode.com/post/how-to-get-last-record-from-leftjoin-table-in-laravel
You need to add two things in here,
1) orderBy descending on prices table.
2) first clause in the DB::table function (It will fetch only 1
record, that will be the latest price).
The solution :
$result = DB::table('products')
->leftJoin('prices',function($join)
{
$join->on('products.id_product', '=', 'prices.id_product')
})->whereRaw(MY_SEARCH_FILTERS)
->orderBy('prices.id_price','desc')
->first();
You can also use (Laravel 5.1) :
$result = DB::table('products')
->leftJoin('products.id','=','prices.id_product')
->whereRaw(MY_SEARCH_FILTERS)
->orderBy('prices.id_price','desc')
->first();