How to write laravel query with left join and a inner join? - laravel

I have following tables, and want to do left join with a condition and another inner join from the left joined table,
User table
id | name
1 john
2 sam
3 cecil
Roles table
id | name
1 admin
2 editor
model_has_roles table
role_id | model_type | model_id
1 App\User 1
2 App\User 2
What I want
Do a left join between user table and model_has_roles table on user.id and model_has_roles.model_id column, if model_type is 'App\User' and then another inner join between Roles table and model_has_roles table for role_id and Roles.id column. So result should be like this,
id | name | role
1 john admin
2 sam editor
3 cecil -
I tried following query but not working correctly,
DB::table('users')->select('id', 'name', 'email', 'created_at', 'role_id')
->leftJoin('model_has_roles', 'model_has_roles.model_id', '=', 'users.id')
->where('model_has_roles.model_type', '=', 'App\User')
->paginate(1);
If you can please help me to write an eloquent query for this.
Thanks
P.S: Actually, I'm using spatie/laravel-permission, and trying to get all the users with their role name.

This should work just fine:
App\User::with('roles')->get();

Related

can i use join in stored procedures - oracle database

I have two tables product and condition where product_id is primary key of product and its foreign key in condition.
product
product_id name
1 eggs
2 milk
condition
product_id condition_name
1 new
2 bad
1 normal
I need a procedure which can give me the name of the all product which is not have bad condition.
You can simply use single query as follows:
select p.name
from product p
where not exists (select 1 from condition c where p.product_id = c.product_id
and c.condition_name = 'bad');

laravel group by fetch latest record from table

I have one table where I want to retrieve data group by the user but I want the latest entry in result how can I do that by using eloquent.
here is an eloquent query I am using.
Product::whereNotNull('user_id')
->orderBy('id','desc')
->groupBy('user_id')
->get();
here is my table
Id Name user_id
-------------------------
1 A 1
2 b 1
3 c 2
4 d 2
5 e 3
6 f 3
result my query is giving me
Id Name user_id
-------------------------
1 A 1
3 c 2
5 e 3
result i want
Id Name user_id
-------------------------
2 b 1
4 d 2
6 f 3
Product::whereRaw('id IN (select MAX(id) FROM products GROUP BY user_id)')
->whereNotNull('user_id')
->orderBy('id','desc')
->get();
You will need a nested query for that, i don't think you can avoid it but this solution should work.
GroupBy happens before OrderBy so you have to get your last record before you do your ordering
Try this :
$subquery = Product::orderBy('id','DESC');
$products = DB::table(DB::raw("({$subquery->toSql()}) as subquery"))
->whereNotNull('user_id')
->groupBy('user_id')
->get();
2nd way : use unique() method in collection (The unique method returns all of the unique models in the collection):
$products = Product::whereNotNull('user_id')
->orderBy('id','desc')
->get()
->unique('user_id');
Check out Laravel Docs
latest / oldest
The latest and oldest methods allow you to easily order results by date. By default, result will be ordered by the created_at column. Or, you may pass the column name that you wish to sort by:
$product = Product::latest()->first();

How to avoid duplicate field name in query result

I am developing a padrino web application. I have two tables:
User table: Has id, name, address fields
Post table: Has id, user_id, content
If I join them,
User.join(:posts, user_id:, :id)
they return two fields with the same name id:
id name address id user_id content
1 jim *** 3 1 post1
I would like to rename each of these ids. I want the result to be:
u_id name address p_id user_id content
1 jim *** 3 1 post1
I am using Sequel adapter for postgresql db in padrino project.
In mysql query, it will be like this:
select u.id as u_id,
u.name,
u.address,
p.id as p_id,
p.user_id as user_id,
p.content
from users u
join posts p on u.id = p.user_id
what should I do?
What I want is not sql query, but code of ruby language. Thanks.
You should use Dataset#select to set which columns are being selected:
User.from{users.as(:u)}.join(Sequel[:posts].as(:p), user_id: :id).
select{[u[:id].as(:u_id), u[:name], u[:address],
p[:id].as(:p_id), p[:user_id].as(:user_id), p[:content]]}

Select records where not in relational table

I have 2 tables with this structures :
**table1**
id | title
-----+--------
1 | Blah1
2 | Blah2
**table2**
id | table1_id | article_id
-----+-------------+------------
1 | 1 | 1
2 | 1 | 3
3 | 2 | 1
Now I want to know how can I select all records from table1 where not use in table2
for example I need all table1 records where not exists in table2 for article_id=3
How can I create model and use eloquent models ?
UPDATE:
I need Blah2 from table1 and then show to my user, because Blah1 inserted for article_id = 3 before.
UPDATE 2:
This is worked query, I need write model for this query:
SELECT a.*
FROM table1 AS a
WHERE a.id NOT IN (SELECT table1_id
FROM table2
WHERE article_id = 3
)
you need to create model something like below you can change name appropriately
here i will refer something like below
table1 => ParentModel and table2 => ChildModel
define relation for children in ParentModel with below method
class ParentModel extends Model {
public function children() {
return $this->hasMany(ChildModel::class, 'table1_id');
}
}
whereDoesntHave method is available to filter records with related model
check here https://laravel.com/docs/5.3/eloquent-relationships#querying-relationship-absence
ParentModel::whereDoesntHave('children', function($q){
// here $q refers to related model in this case ChildModel
$q->where('article_id', 3);
})->get();
above query should return the required results.

Laravel: Sorting a column in the Left Join

Lets say I have a simple table of users
id | userName
3 Michael
4 Mike
5 George
And another table of their cars and prices
id | belongsToUser | carPrice
1 4 5000
2 4 6000
3 4 8000
I would like to do a left join that would return the highest or lowest carPrice
At the moment, the query would return the last/first instance of that users carPrice.
I've tried entering the orderBy in various join queries but to no avail.
I have a helper function that would return the highest/lowest price on demand but I'm not sure how that would fit within this query as I would like to use laravels inbuilt paginate
This is the aggregate problem so here is the solvation:
DB::table('users')
->leftJoin('carPrices', 'belongsToUser', '=', 'users.id')
->select('users.*', DB::raw('MAX(carPrice) as highestCarPrice'), DB::raw('MIN(carPrice) as lowestCarPrice'))
->groupBy('users.id')
->get();

Resources