Laravel, load relationships using JOIN - mysql

We all know that using the Eloquent with('relation') function is not doing a JOIN , but it's making another query to get the relationship.
Is there a way to make a single query using JOIN so we can reduce our MySQL queries ?

As far as I know it's not possible to use JOIN when using Eloquent objects. This is how Eloquent work - it doesn't use joins, it uses separate queries to get related data. So if you want to use joins, you won't be able to use Eloquent objects.

You could create a VIEW in database, and then, create a model in your app. Updated data in VIEW is automatically updated in the related tables. Could be a workaround.

Yeah something like this if you want to do a left join ( use ->join() for a simple inner join)
$query = DB::table('product');
$query->leftJoin('user', 'product.seller_id', '=','user.user_id');
return $query->get();
See the query builder docs for further details: http://laravel.com/docs/4.2/queries#joins

Related

how i can write this join query in laravel

SELECT text
FROM localization
LEFT JOIN countries
ON countries.country_name_key = localization.key
WHERE countries.country_name_key = localization.key
AND localization.lang = 'ar';
I need to write this query in laravel with eloquent model without relations between the model .
I aggree with MrMarlow. Without Eloquent, you have to use Query Builder. But I think, i have different query:
$results = DB::table('localization')
->leftJoin('countries','countries.country_name_key','localization.key')
->where('countries.country_name_key','localization.key')
->where('localization.lang', 'ar')
->select('localization.text')
->get();
With leftJoin in the query will show all text in localization table altough no relation in countries. So, i think it no need leftJoin to show localization.text field because you just want to show the localization.text field in localization table only.
It works in laravel 5.6.
Hope this helps.
It is my understanding that Eloquent has to use models with relationships to be able to query effectively, so to the best of my (limited) knowledge, I do not believe it's possible.
However, Laravel does ship with Query Builder which will handle this just fine.
Query Builder
By using the DB facade (Illuminate\Support\Facades\DB) you can create the query like so;
$results = DB::table('localization')
->join('countries', 'localization.key', '=', 'countries.country_name_key')
->where('countries.country_name_key', '=', 'localization.key')
->where('localization.lang', '=', 'ar')
->pluck('text');
Documentation for explanation/further research, can be found within the Laravel 5.6 Query Builder Documentation
Edit
If you do decide you must use eloquent, you can create models for existing database tables using something like reliese/laravel, but you would then need to create relationship mapping etc.

How to make Query Builder By Update Join 2 Tables In The Phalcon

I want to make QueryBuilder on the Update Join 2 Tables. But I don't know sintaks it. Please Write codes to me about how to make it. I give example query of the following below:
UPDATE Teachers
INNER JOIN Education
ON Education.id=Teachers.id
SET
Teachers.userid=:userid:,
Teachers.fullname=:fullname:,
Teachers.birthday=:birthday:,
Teachers.gender=:gender:,
Teachers.currentjob=:currentjob:,
Education.primaryschool=:primaryschool:,
Education.juniorhighschool=:juniorhighschool:,
Education.seniorhighschool=:seniorhighschool:,
WHERE Teachers.id=:id:
As far as i know PHQL doesn't allow update like this. When you write PHQL update query in phalcon it'as actually making SELECT query, and calling update method to make sure all the events, validation etc are fired for the models. With joins this is obviously a problem how to exactly do it, beacause you might join some model which doesn't have relations provided.
Phalcon just don't support JOINS with UPDATE, you need to use raw query.

Are sub queries the only way I can use query data for new queries?

Using the definition of sub queries as specified by http://www.tutorialspoint.com/sql/sql-sub-queries.htm
I'm going to get data from my first three tables, and I'll use it to query other tables. This will happen again twice to get to the data the user needs. I tried searching on google "How to use queries to write queries in SQL" or "How to use data returned from table to query another table?". However, not exactly getting the information I need. Perhaps I'm missing something or asking the wrong question.
I think you're looking for joins.
Example:
SELECT * FROM cc_courses
JOIN equivalencies
ON cc_courses.id = equivalencies.cc_course_id
JOIN uni_courses
ON equivalencies.uni_course_id = uni_courses.id
I guess I was looking for Joins after all.

Why Laravel does not optimize model queries automatically?

Till today I was relying on Laravel relationships, but since I opened mysql logs I was very disappointed.
When I execute code
Company::with(['users', 'machines'])->get()
mysql.log looks this way
select * from `company` where `company`.`id` = '48' limit 1
select * from `user` where `user`.`company_id` in ('48')
select * from `machine` where `machine`.`company_id` in ('48')
Why Laravel does not use joins for eager fetching? Also, are there any ways of improving perfomance and still using Laravel Models?
I know that Doctrine ORM eager loading works pretty nice by using joins.
Thank you for your help.
If you really want to use joins instead of the Eloquent computed queries, I suppose you could just use the fluent query builder (that comes shipped with Laravel through the DB facade) and stick that code into a method of your model to keep everything nice and SRP.
For instance:
class Company extends Model {
public function sqlWithJoin() {
$users = DB::table('company')
->leftJoin('user', 'company.id', '=', 'user.company_id')
->get();
return $users;
}
}
This would generate a proper join query for you.
As for why you would want to do this, you would have to benchmark both options to see which one gives you the best performance for your specific data. I wouldn't generalize that one option always has better/worse performance than the other.
As stated in the comments, I'm not sure performance-wise why this is the preferred method, but from usability, being able to access a model's relationships as it's own separate property is much easier than working with a join, especially in the event of a many-to-one relationship.
Let's compare the above example using both ->with() and ->leftJoin() methods.
When using ->with() every relationship is defined as a property of Company, accessed via $company->users. It's easy to run a foreach() loop over this property foreach($company->users AS $user) and output information, such as username, email, etc. Also, if the Company has no users, you don't have to worry about displaying empty values (especially important on chaining models using . notation, such as users.user_details).
Now, looking at leftJoin(). If you try to chain multiple leftJoins() on each model and their sub-models, there's a chance you won't get the results you're expecting. Essentially, leftJoin() doesn't handle NULL records as well as individual queries can.
Next, to output a list of a company's users, you would have to run a loop such as:
foreach($company AS $row){
echo $row->username;
echo $row->email;
// etc etc
}
This becomes problematic as Eloquent doesn't handle duplicate properties well at all. For example, if the company has an email field as well as the user, it's anyone's guess which is actually displayed. Unless you do a selectRaw("companies.email AS email, users.email AS user_email)", only one email property is going to be returned. This also applies to columns like id, where multiple are going to be fetched by using leftJoin(), but only one will actually be accessible.
Long story short, leftJoin() comes with the potential for a lot of issues when trying to join multiple tables with the possibility of duplicate information, null information, etc. While the performance of running multiple queries using the ->with() method may not be the best, it allows for easier use in retrieving and displaying information.

How to Query & re-organize Data from current MySQL database?

I have the following database structure:
And the data stored inside is as follows:
However, I like to select data from this database in the following format:
How can I use one single SELECT statement to achieve this? If using one single SELECT statement cannot, how to achieve this by whatever sql code? Can someone give me the implementation?
Can I use one single SELECT statement to achieve this?
Yes, you can. You will have to play a little with JOIN and GROUP BY statement, but it can be achieved.
EDIT:
Let's try multiple JOIN statements:
Select sum.name, x0.y_value, x10.y_value, x20.y_value
from test_summary as sum
join test_details as x0 on sum.id=x0.id and x0.x_value=0
join test_details as x10 on sum.id=x10.id and x10.x_value=10
join test_details as x20 on sum.id=x20.id and x20.x_value=20
Based on answers to multiple joins and join with where clause
The things you like called pivot table, and this is out of scope of relation data base system like mySQL. So there many special platforms for OLAP. But if you do not need any comprehensive OLAP things, but produce some pivot tables using mySQL and PHP you do not need any special sql, but nedd to program such presentation by php, may be using some commercial frameworks like this or some opensource code