If statement in Laravel Eloquent - php

I have two Models which are joined through three id's to one 1 id. The model AdviceProtocol had three ids defined: threshold_category1_id, threshold_category2_id and threshold_category3_id. These are all three linked to id from the model Categories. The threshold_cateogry_id's can be a number linked to the categories.id, or null.
In my query, I need to go through three of the threshold_catogory_ids and if they are NOT NULL, retrieve the categories.name. The query that I have now:
$advicePreparationsQuery = AdviceProtocol::select(['advice_protocols.name', 'advice_protocols.category', 'questions.name AS question_name', 'categories.name as Category_Name','categories.name as Category_Name2'])
->join('questions', 'advice_protocols.user_goal_id', '=', 'questions.id')
->join('categories', function ($join)
{
$join->on('advice_protocols.threshold_category1_id', '=', 'categories.id')->orOn('advice_protocols.threshold_category2_id', '=', 'categories.id')->orOn('advice_protocols.threshold_category3_id', '=', 'categories.id');
})
This query now returns the same category.name twice.
I have tried to look up how other people have solved this problem, but i couldn't find something accurate online.

I'd try three joins with three different alias and then grab the name for each category name of each different alias:
$advicePreparationsQuery = AdviceProtocol::select(['advice_protocols.name', 'advice_protocols.category', 'questions.name AS question_name', 'categories1.name as Category_Name','categories2.name as Category_Name2','categories3.name as Category_Name2'])
->join('questions', 'advice_protocols.user_goal_id', '=', 'questions.id')
->join('categories as categories1', 'advice_protocols.threshold_category1_id', '=', 'categories1.id')
->join('categories as categories2', 'advice_protocols.threshold_category2_id', '=', 'categories2.id')
->join('categories as categories3', 'advice_protocols.threshold_category3_id', '=', 'categories3.id');

Use group by name in query ie ->groupBy('category.name')
$advicePreparationsQuery = AdviceProtocol::select(['advice_protocols.name', 'advice_protocols.category', 'questions.name AS question_name', 'categories.name as Category_Name','categories.name as Category_Name2'])
->join('questions', 'advice_protocols.user_goal_id', '=', 'questions.id')
->join('categories', function ($join)
{
$join->on('advice_protocols.threshold_category1_id', '=', 'categories.id')->orOn('advice_protocols.threshold_category2_id', '=', 'categories.id')->orOn('advice_protocols.threshold_category3_id', '=', 'categories.id');
}
->groupBy('category.name'))

Related

Laravel join query is showing wrong results

I have 4 tables clinics , locations , services & location_services in which relations are clinicid is present in locations and both serviceid and location id is present in location_services table.
My requirement is that i want to retrive all the cinics and their coreesponding locations and services .
But when i tried it is retrving the results of only one clinic id , i dont know how can i retrive complete list
following is my code
$clinic = Clinic::find($id);
$locations = Location::where('clinicID', $id)->get();
$locationservices = Service::select('services.serviceName as servicename','locations.locationID as locid','locations.locationName as locname')
->join('location_services', 'location_services.serviceID', '=', 'services.serviceID')
->join('locations', 'locations.locationID', '=', 'location_services.locationID')
->join('clinics', 'clinics.clinicID', '=', 'locations.clinicID')
->where('clinics.clinicID','=',$id)
->toSql();
dd($locationservices);
die();
Please help me to solve this
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();

How to get data from another table from database?

I want to get data from table role_users , column role_id . For the moment, I have this in my controller :
$data['contact_users'] = DB::table('contacts')
->join('users' , 'users.id', '=', 'contacts.contact_id')
->join('industries' , 'industries.id', '=', 'users.industry_id')
->join('countries' , 'countries.id', '=', 'users.country_id')
->join('organization_types' , 'organization_types.id', '=', 'users.organization_type_id')
->select('users.*','industries.industry','countries.country','organization_types.organization_type')
->where('contacts.contact_id','!=',$id)
->where('users.deleted_at','=',NULL)
->whereIn('contacts.user_id', $contact_id)
->whereNotIn('contacts.contact_id', $contact_id)
->whereNotIn('contacts.contact_id', $inviter_id)
->groupBy('contact_id')
->take(4)
->get();
I'm using it in view with this code :
{{$contact->industry_id}} or {{$contact->country_id}}
I need to use something like this.
{{$contact->role_id}}
which is working for every user.But I need to get data from role_users,column role_id.I don't know how to use ->join() and I need it so much.Thank you.
I added one extra join and one select field at the end,
$data['contact_users'] = DB::table('contacts')
->join('users', 'users.id', '=', 'contacts.contact_id')
->join('industries', 'industries.id', '=', 'users.industry_id')
->join('countries', 'countries.id', '=', 'users.country_id')
->join('organization_types', 'organization_types.id', '=', 'users.organization_type_id')
->join("role_users", "role_users.user_id","=","users.id")
->select('users.*', 'industries.industry', 'countries.country', 'organization_types.organization_type', "role_users.role_id")
->where('contacts.contact_id', '!=', $id)
->where('users.deleted_at', '=', null)
->whereIn('contacts.user_id', $contact_id)
->whereNotIn('contacts.contact_id', $contact_id)
->whereNotIn('contacts.contact_id', $inviter_id)
->groupBy('contact_id')
->take(4)
->get();

Laravel: Query with where clause gone wrong

What I am trying to achieve is to allow teachers to import a student into different classes.
Note: A student can be multiple classes.
The problem is that when I show the list of students in a select dropdown it should return all students except for students that are not in this class (the class being the page that I am on, app.com/classes/5 for example).
$students = User::join('group_user', 'users.id', '=', 'group_user.user_id')
->role('student')
->where('group_user.group_id', '!=', $id)
->orderBy('users.name', 'asc')
->get();
This works and shows all students that are not in this specific class BUT if a student that's in this class and another class their name appears in the list and as duplicate names.
What can I do?
When MySQL's only_full_group_by mode is turned on, it means that strict ANSI SQL rules will apply when using GROUP BY
You should try to select fields from schema on which you can apply group by instead of select *.
$students = User::join('group_user', 'users.id', '=', 'group_user.user_id')
->role('student')
->where('group_user.group_id', '!=', $id)
->select('users.id', 'other fields you used')
->orderBy('users.name', 'ASC')
->groupBy('users.id')
->get();
Not IN is also useful in your case
User::select('fields you used')
->role('student')
->whereNotIn('id', DB::table('group_user')->where('group_id', $id)->pluck('user_id')) // $id = 5
->orderBy('name', 'ASC')
->get();
Modify your query to use distinct() like so;
$students = User::join('group_user', 'users.id', '=', 'group_user.user_id')
->role('student')
->where('group_user.group_id', '!=', $id)
->orderBy('users.name', 'ASC')
->distinct()
->get();
You could also groupBy('users.id')
$students = User::join('group_user', 'users.id', '=', 'group_user.user_id')
->role('student')
->where('group_user.group_id', '!=', $id)
->orderBy('users.name', 'ASC')
->groupBy('users.id')
->get();

Laravel/Eloquent query going wrong

I have two tables, one with users, one with the name of their document. The first table consists of two columns: id and username. The second one consists of three columns: id, userid and document_name.
Now, I'm trying to create a query in the controller. What should happen, ideally, is that if someone visits website.com/{documentname}, it displays the username of the owner. Also, this should only happen if the current logged in user is the owner of the document. However, this is proving more difficult than I imagined. As in, I can't see what I'm doing wrong.
Here's the query:
$user = DB::table('documents')
->join('users', function($join)
{
$join->on('users.id', '=', 'documents.userid')
->where('documents.userid', '=', Auth::id())
->where('documents.document_name', '=', $document_name);
})
->get();
**Try this query :**
$user = DB::table('documents')
->leftJoin('users', 'users.id', '=', 'documents.userid')
->where('documents.userid', '=', Auth::id())
->where('documents.document_name', '=', $document_name);
->get();
$document_name isn't in scope for the join function: you need to pass it through to the closure via use
$user = DB::table('documents')
->join('users', function($join) use ($document_name)
{
$join->on('users.id', '=', 'documents.userid')
->where('documents.userid', '=', Auth::id())
->where('documents.document_name', '=', $document_name);
})
->get();
EDIT
Because the WHERE conditions apply to the base table, and not to the JOIN:
$user = DB::table('documents')
->join('users', function($join) {
$join->on('users.id', '=', 'documents.userid')
})
->where('userid', '=', Auth::id())
->where('document_name', '=', $document_name);
->get();

Laravel join queries AS

Any way of defining an AS for a query??
I have tried the following:
$data = News::order_by('news.id', 'desc')
->join('categories', 'news.category_id', '=', 'categories.id')
->left_join('users', 'news.user_id', '=', 'users.id') // ['created_by']
->left_join('users', 'news.modified_by', '=', 'users.id') // ['modified_by']
->paginate(30, array('news.title', 'categories.name as categories', 'users.name as username'));
The problem is that ['name'] from categories will be replaces with the one from users. Any way of having them with different names?
Having the aliases above... how can I create an alias where both joins return users.name ?
paginate() method's second parameter accepts array of table columns to select in the query. So this part:
paginate(30, array('news.title, category.name'));
must be like this:
paginate(30, array('news.title', 'category.name'));
UPDATE (after you changed the question)
Try this:
->paginate(30, array('news.title', 'categories.name as category_name', 'users.name as user_name'));
UPDATE 2 (after you changed the question, again)
You can use alias on tables, too:
$data = News::order_by('news.id', 'desc')
->join('categories', 'news.category_id', '=', 'categories.id')
->join('users as u1', 'news.user_id', '=', 'u1.id') // ['created_by']
->join('users as u2', 'news.modified_by', '=', 'u2.id') // ['modified_by']
->paginate(30, array('news.title', 'categories.name as categories', 'u1.name as creater_username', 'u2.name as modifier_username'));
More simple and plain answer to this question is and what I was looking for that Eloquent supports aliases directly with table names or columns, for example:
$users = DB::table('really_long_table_name AS t')
->select('t.id AS uid')
->get();

Categories