This is the query I currently using for Inner Join in my laravel app:
public function getReservationListAPI()
{
$id = JWTAuth::parseToken()->authenticate()->id;
$result = DB::table('pporders AS ord')
->join('products AS pd', 'ord.product_id', '=', 'pd.id')
->select('ord.*')
->where('pd.user_id',$id)
->get();
dd($result);
}
How can I wrote this query in Eloquent form? Thanks!!
EDIT
Relationship:
Product hasMany Order
Order belongsTo Product
User hasMany Product
Product belongsTo User
It depends on your relation, but something like this:
Pporders::with(['product' => function($q) use($id) {
$q->where('user_id', $id);
}])->get();
But it won't make the same sql query what you described, but gives the same result.
Related
SELECT
posts.id,
(select count(*) from post_likes where post_id = 13 and user_id = 12) as post_like
FROM
posts
LIMIT 5
How to write this query in Laravel query builder?
If your ORM models are defined (and you have both Post and PostLike models), create a relationship in your Post.php model (if not already), like:
public function likes(){
return $this->hasMany(PostLike::class);
}
Then if you only need the count, try something like:
$userId = 12;
$postList = Post::query()
->whereId(13)
->withCount(['likes', 'likes AS post_like' => function ($query) use($userId) {
$query->where('user_id', '=', $userId);
}])
->limit(5)
->get();
// Then do something with result.
foreach ($postList as $post) {
$count = $post['post_like'];
}
Note that above we use post_like alias, and limit to user_id, just to much OP requirements; Else we could simply set likes_count to the number of relations, like:
->withCount('likes')
But you could use relationship for subquery with the whereHas(...) eloquent method, like:
Post::query()->whereHas('likes', function($query){
$query->where(...your statements for sub query go there);
}, '>', 4)->limit(5)->get(); //Select where more than 4 relation found with given parameters
For more see: https://laravel.com/docs/8.x/eloquent-relationships#querying-relationship-existence
I have 3 models Supplier, Purchase and PurchaseDetail.
To join the Supplier model with PurchaseDetail through Purchase I have created a hasManyThrough relation.
hasManyThrough inside Supplier model:
public function detail_purchases(){
return $this->hasManyThrough(PurchaseDetail::class, Purchase::class);
}
The relationship works well and I can count the quantities purchased from sellers as follows:
$collectors = Supplier::withCount(['detail_purchases as qty_sold' => function($query) {
return $query->select(\DB::raw('SUM(qty)'))
->where('unit', '=', 'kg');
}])
->where('supplier_type','=','persona_natural')
->orderBy('qty_sold','desc')
->get();
SQL Query output:
select `suppliers`.*, (
select SUM(qty)
from `purchase_details`
inner join `purchases` on `purchases`.`id` = `purchase_details`.`purchase_id`
where `suppliers`.`id` = `purchases`.`supplier_id`
and `unit` = 'kg'
and `purchases`.`deleted_at` is null
) as `qty_sold`
from `suppliers`
where `supplier_type` = 'persona_natural'
order by `qty_sold` desc;
Output rows:
My problem is that this query is bringing me sellers that I did not make purchases from them, I don't know why they infiltrate the query if it is assumed that the hasManyThrough relationship only joins those who are registered in Purchase or made purchases from them.
Also the Supplier model has another relation called purchases:
public function purchases() {
return $this->hasMany(Purchase::class, 'supplier_id');
}
And the model Purchase has a relation hasMany with PurchaseDetail :
public function details(){
return $this->hasMany(PurchaseDetail::class, 'purchase_id');
}
Updated
Using whereHas now I can get all the suppliers that I did purchases however the qty_sold is not appearing in the results:
$collectors = Supplier::whereHas('purchases', function($query){
$query->withCount(['details as qty_sold' => function($query){
$query->select(\DB::raw('SUM(qty)'))
->where('unit', '=', $this->unit);
}]);
})
->where('supplier_type','=','persona_natural')
->get();
This selection is important because I want to know how many kgs of all products I purchased.
Thanks #Tony
In your updated query can you move the withCount out of the subquery? So you would have Supplier::withCount(...)->whereHas('purchases')..
Ok, I fixed it, adding first the whereHas directive the I used the hasManyThrough
relation with withCount. Of this way only suppliers that has purchases are selection.
$collectors = Supplier::whereHas('purchases')
->withCount([
'detail_purchases as qty_sold' => function($query){
$query->select(\DB::raw('SUM(qty)'))
->where('unit', '=', 'kg');
}
])
->where('supplier_type','=', 'persona_natural')
->get();
I'm making an attempt to write Eloquent join query but i didn't get the result i wanted.
i have 2 table
products which contains all information about products
category_product contains product_id and category_id
i just want to select all information about products which their category_id is equal to 2
After you have belongsToMany relation between categories and products.
Product::whereHas('categories', function($query){
$query->where('id',2);
})->with('categories')->get();
I can offer you a solution like this
class Product extends Model
{
public function category()
{
return $this->morphToMany(Category::class, 'category_product table');
}
}
class Category extends Model
{
public function product()
{
return $this->morphedByMany(Product::class, 'category_product table');
}
}
in Controller
$products = DB::table('products')
->join('category_product', 'products.id', '=', 'category_product.products_id')
->select('products.*')
->where('category_product.category_id','=',2)
->get();
How can I order a result set by something on its relationship?
I am trying to get the Eloquent equivalent of this:
SELECT * FROM users INNER JOIN roles ON users.role_id = roles.id ORDER BY roles.label DESC
Here is what I am trying (based on the documentation):
$order = 'desc';
$users = User::with(['role' => function ($q) use ($order) {
$q->orderBy('label', $order);
}])->paginate(10);
but it doesn't order them properly. What am I doing wrong?
EDIT: Not sure if showing the model relationship is relevant but here it is:
public function role()
{
return $this->belongsTo(Role::class);
}
You should do it with join
User::with('role')->join('role', 'role.id', '=', 'users.id')->orderBy('role.label', $order)->paginate(10);
I am trying to convert the following database query to use Eloquent:
$orderitems = DB::table('order_items')
->join('orders', 'orders.id', '=', 'order_items.order_id')
->where('orders.status', 1)
->where('order_items.sku', $sku)
->select('order_items.*')
->get();
I've tried the following:
$orderitems = Item::where('sku', $sku)
->with(['order' => function ($query) {
$query->where('status', 0);
}])
->get();
but it seems to be bringing back more results than it should. I can see from using DB::getQueryLog that the order_items query is not joining with the orders table:
select * from `order_items` where `stock_code` = ? and `order_items`.`deleted_at` is null
Do I need to create a new relationship between orderitems and order and add the additional where into that?
Relationships:
Order hasMany Items
Item hasOne Order
Solution was to use Query Scopes https://laravel.com/docs/5.7/eloquent#query-scopes
In the controller:
$orderitems = Item::stock($sku)->paginate(10);
In the orderitems model:
public function scopeStock($query, $sku)
{
return $query->join('orders', function ($join) {
$join->on('orders.id', '=', 'order_items.order_id');
$join->where('orders.status', '=', 1);
})
->select('order_items.*', 'orders.order_date')
->where('order_items.sku', $sku);
}