Convert Query to Eloquent - sql

How to make that query with eloquent
SELECT employees.first_name, companies.name FROM employees
JOIN companies ON employees.company_id = companies.id
My relationships
public function employees()
{
return $this->hasMany(Employee::class);
}
public function company()
{
return $this->belongsTo(Company::class);
}
I fetching the name with a given ID, but how can I find it for all. Or maybe I am thinking wrong
$employee = $employee->all()->find($id)->company->name;

I assumed your employees Model name as Employee and companies Model name as Company
$employees = Employee::with('company')->get();
if(!empty($employees)){
foreach($employees as $employee){
echo $employee->first_name;
echo $employee->company->name;
}
}
If you want to search per id then you may do as below.
$employee = Employee::with('company')->find($id);
echo $employee->company->name;

$employee = Employee::where('employees.id',$id)
->join('companies','companies.id','=','employees.company_id')
->select('employees.first_name', 'companies.name')
->first();

Firs Of all this is very bad practice:
$employee = $employee->all()->find($id)->company->name;
This returns all employee collection and then searches id in it. You can simply use Employee::find($id)
Now about your query, as I guess your company model has many employee and if you want to find all company employees you have to do like that:
$company->employees()->select('first_name')->get(); // Collection of Employee
If you want to get specific company employee with employee id you can do:
$company->employees()->select('first_name')->where('id', $id)->first(); // null or Employee

Related

Join multiple tables used as Indexing - Laravel

I have three tables - Chairman, Designation, Members.
MY requirement is to map the member to chairman and assign member a role.
I was able to fetch the list of members under the chairman when I had chairman_id and designation_id in the members table.
Since the chairman change, most of the members stay intact. So I came up with an idea of indexing them
Table - membermap
id | chairman_id | designation_id | member_id
So the list is preserved how many chairmans come and go. I dont need to create new profile for new chairman rather than map to it.
I am now sure how do I do it,
So far I was able to pull the ID but I am not sure how do I join the tables
Tables
Chairman
id| name
Designation
id|designation
Members
id|members
Here is my controller
$mapmember = Statechairman::findOrFail($id)->statechairmembersmap;
dd($mapmember);
In this Iam getting the statechairmembersmap but it's fetching all the result and not limiting the match.
I also tried to join the query using the DB
$mapmember = DB::table('statechairmen')
->join('state_chairman_members_maps', 'state_chairman_members_maps.chairman_id','statechairmen.id')
->join('statemembers','statemembers.id','state_chairman_members_maps.members_id')
->select('state_chairman_members_maps.*')->get();
but this result show me the Table - membermap but not the other results.
My Models:
Chairman :
public function statechairmembersmap(){
return $this->hasMany('App\StateChairmanMembersMap','chairman_id','id');
}
public function statemembers(){
return $this->hasMany('App\Statemembers','chairman_id', 'id');
}
public function statedesignation(){
return $this->hasMany('App\Statedesignation','id','designation_id');
}
membermap:
protected $table = 'state_chairman_members_maps';
protected $dates = ['deleted_at'];
public function statechairman(){
return $this->belongsTo('App\Statechairman','id');
}
public function statedesignations(){
return $this->belongsTo('App\Statedesignation','designation_id','id');
}
public function statemembers(){
return $this->belongsTo('App\Statemembers','members_id','id');
}
Please assist me where I doing wrong.
Thanks a lot for checking the question out.
Finally after a lot of strugle, I was able to find it by myself.
$mapmembers = DB::table('state_chairman_members_maps')
->join('statechairmen','statechairmen.id','=','state_chairman_members_maps.chairman_id')
->join('statemembers','statemembers.id','=','state_chairman_members_maps.members_id')
->join('statedesignations','statedesignations.id','=','state_chairman_members_maps.designation_id')
->where('chairman_id','=',$id)
->get();
Here is what I came up with.
Here I have joined 3 tables and mapped the id comming from the chairman to filter the result. I getting the results.

Where condition along with group_by oprion in rails

I am new to rails so please anybody tell me how to use group_by option in controller page and and along with group_by i want to count the name through the Where Condition
In City Model add a scope.
scope :by_name, lambda { |name| where(name: name) }
When you call count on the scope
City.by_name('London').count
The following MySql will be executed...
SELECT count(*) FROMcitiesWHEREcities.name= 'London'
City.group_by(&:name)
The above statement will give you array of hash, in which key will be city_name and values will be array of city records.
Then if you need only count of each of array of city records for all the cities then you can do it by creating a new variable and storing the count of records along with their name using :
city_count = {}
City.group_by(&:name).each do |city_name, city_records|
city_count[city_name] = city_records.count
end
The above code will return you the array of hash which has key as city_name and the number of records as value.

YII: Dropdownlist with relation

DB table:
Mcourse(Master course )-> contains Course Names
Lcourse(Linked
Course- courses belongs to a college) -> contains foreign key
Mcourse_Id. & college Id.
Nw the problem is
I want to display list of courses available in a college using dropdownlist.
So sql query is:
select Lcourse_Id, Mcourse_Name* from Lcourse inner join Mcourse on Lcourse_Mcourse_Id=Mcourse Id..
*Id & value pair for dropdownlist
I could do this usin createCommand..Its working pretty fine. But i cant do this usin Relations ..Help me.
Let's imagine for a minute that your Mcourse table is called courses and model for that table is called Courses, your Lcourse table is called courses_colleges and your colleges table is colleges and model for that table is Colleges
Now, You should have Courses model with relations:
public function relations() {
return array(
'colleges' => array(self::MANY_MANY, 'Colleges', 'courses_colleges(course_id, college_id)')
);
}
Your Colleges model should have similar relations:
public function relations() {
return array(
'courses' => array(self::MANY_MANY, 'Courses', 'courses_colleges(college_id, course_id)')
);
}
Now if you want to print out a dropdown with all courses available for a certain college. In your controller action method get the model of that college including its courses:
public function actionShow() {
$id = 1; // We set just some sample id. You could get it from request ofc.
$college = Colleges::model()->with('courses')->findByPk($id);
$this->render('show', array('college'=>$college));
}
Now in your view print out this:
echo CHtml::dropDownList('courses', '', CHtml::listData($college->courses, 'id', 'name'));
Where 'id' and 'name' are columns of your Courses model.
Something like that.
The error is in the listData() function in your view, specifically that you don't have a mc_Id in your Lcourse model.
As you haven't clarified the model that each of those relationships are assigned with, it's impossible to guess what you should substitute for 'mc_Id' in your view - check your Lcourse model to determine the proper column name.

Selecting a collection does not result in exception in JPA 2

I am having a bit of a trouble understanding this line of code from the book Pro JPA 2
According to the book on page 181.
The result type of a select query cannot be a collection; it must be a
single valued object such as an entity instance or persistent field
type. Expressions such as e.phones are illegal in the SELECT clause
because they would result in Collection instances (each occurrence of
e.phones is a collection, not an instance). Therefore, just as with
SQL and tables, if we want to navigate along a collection association
and return elements of that collection, we must join the two entities
together.
Please consider this entities below with relationship mapping
#Entity
public class Employee {
..
#OneToMany(mappedBy="employee", cascade=CascadeType.ALL, targetEntity=Phone.class)
private Collection<Phone> phones = new ArrayList<Phone>();
..
}
#Entity
public class Phone {
..
#OneToOne
private Employee employee;
..
}
Now in a test class i tried it with this test case
#Test
public void selectCollectionTest(){
TypedQuery<Object> query = em.createQuery("select e.phones from Employee e where e.id = 1", Object.class);
List<Object> empList = query.getResultList();
for(Object temp: empList){
System.out.println(temp);
}
}
I was expecting that an exception would be thrown but nothing is happening and I was able to select the collection?
Is this correct? Can somebody explain or clear out my understanding?
Eclipselink
EclipseLink allows this, it is an extension, the JPA spec does not support it.
It is the same as the query,
select p from Employee e join e.phones p where e.id = 1
Try to run your query with below code by removing the where clause:
select e.phones from Employee e, Object.class
The point i am trying to make is may be your result for emp id 1 contains only single phone object.

Nhibernate - How do I get ordered distinct results with QueryOver?

public class City
{
virtual public long Id { get; set; }
virtual public string Name { get; set; }
}
City table contains duplicated Names and I want to remove duplicates. I also want the results to be ordered by Id.
First I thought about the following query.
select distinct Name from City order by Id;
But this breaks with 'ORDER BY items must appear in the select list if SELECT DISTINCT is specified.' exception. After seeing http://weblogs.sqlteam.com/jeffs/archive/2007/12/13/select-distinct-order-by-error.aspx I think I should do:
select Name from City group by Name order by min(Id)
So my question is how can I do this query with QueryOver?
This is possible in ICriteria:
var list =
session.CreateCriteria<City>()
.SetProjection(Projections.Group("Name"))
.AddOrder(Order.Asc(Projections.Min("Id")))
.List<string>();
But this is not currently possible in QueryOver, because the .OrderBy(IProjection) overload is missing. Once the missing overload has been added it should look something like:
var list =
s.QueryOver<City>()
.Select(Projections.Group<City>(p => p.Name))
.OrderBy(Projections.Min<City>(c => c.Id)).Asc
.List<string>();
Note that the Projections overloads are there just now, so you can write the following (typesafe) query in ICriteria:
var list =
session.CreateCriteria<City>()
.SetProjection(Projections.Group<City>(c => c.Name))
.AddOrder(Order.Asc(Projections.Min<City>(c => c.Id)))
.List<string>();
So, what I've found is pretty simple...
var query = session.QueryOver<MyModel>()
// Conditions here
.OrderBy(m => m.GetThisDistinctField).Desc() // ...or Asc()...
.SelectList(m => m.SelectGroup(g => g.GetThisDistinctField));
var result = query.List<FieldDataType>().ToList();
return result;
To get an ordered query in queryover, start with a query that includes whatever criteria you need, but then add the SelectList/SelectGroup setup in order to get the distinct list. In other words, it's sort of like NHibernate can take a regular query, and then do special stuff to make it a select distinct query.
This is a solution I'm using in a current project I'm working on; I hope it helps someone else too.