I have been trying to convert a right join query to left join query in order to use it inside laravel query builder. Here is my Sql statement and it result wich works flawlessly
select `weekday`.`name`, `open_time`, `close_time`
from `schedule`
join `restaurants_has_schedule` on `schedule`.`id` = `restaurants_has_schedule`.`schedule_id`
and `restaurants_has_schedule`.`restaurants_id` = 1
right join `weekday` on `weekday`.`id` = `schedule`.`weekday_id`
ORDER BY `weekday`.`id`
|------
|name|open_time|close_time
|------
|Domingo|NULL|NULL
|Lunes|NULL|NULL
|Martes|NULL|NULL
|Miercoles|NULL|NULL
|Jueves|14:11:51|14:11:51
|Vienes|09:11:21|17:00:00
|Sábado|NULL|NULL
but when convert It to left join it stop working, displaying me the same data for every single restaurants_id. This is my left join statement.
select `weekday`.`name`, `open_time`, `close_time`
from `weekday`
left join `schedule` on `weekday`.`id` = `schedule`.`weekday_id`
join `restaurants_has_schedule` on `schedule`.`id` = `restaurants_has_schedule`.`schedule_id`
and `restaurants_has_schedule`.`restaurants_id` = 1
ORDER BY `weekday`.`id`
What am I doing wrong? Is There another alternative? Thak you in advance
Try use Laravels Eloquent ORM, which handles relationships really cool! no need anymore to concat or write sql-queries
See here about: Laravels Eloquent ORM & Schema Builder
Or maybe about orm's in general, you should really give it a try:
Object Role Modeling
Object Role Modeling
Example from Laravel doc:
One Post may have many comments
One to many:
class Post extends Eloquent {
public function comments()
{
return $this->hasMany('Comment');
}
}
Where 'Comment' is the model.
The "reverse" to define:
class Comment extends Eloquent {
public function post()
{
return $this->belongsTo('Post');
}
}
Where 'Post' is the model.
And then as query:
$comments = Post::find(1)->comments; //by Primary Key
Or
$comments = Post::where('somefield', '=', 'somevalue')->comments->get();
....Really cool, for many to many see the docs#Laravels Eloquent ORM
Related
I'm new to laravel. Here is my query that filters out the quizes that don't have any problem (questions) or the problems don't have any answers. but I'm not sure how to write it properly using laravel query builder. Considering I'm using eloquent to build relationships Would be even better if I could get the same result using laravel eloquent.
SELECT DISTINCT q.id, q.content
FROM m_quiz q
RIGHT JOIN (SELECT DISTINCT p.quiz_id as id
FROM m_problem p
RIGHT JOIN m_answer_choice a
ON p.id = a.problem_id) problem
ON q.id = problem.id
ORDER BY q.id;
Not tested but I think it would be something like this.
DB::table('problems')->selectRaw('m_problem.*, DISTINCT m_problem.quiz_id as id')
->join('m_answer_choice', 'm_problem.id', '=', 'm_answer_choice.problem_id')
->groupBy('m_problem.id')
->get();
But it would be better if you can do something like
namespace App;
use Illuminate\Database\Eloquent\Model;
class Problem extends Model
{
/**
* Get the comments for the blog post.
*/
public function answerChoices()
{
return $this->hasMany('App\AnswerChoices');
}
}
and do something like
$answerChoices= App\Problem::find(1)->answerChoices;
foreach ($answerChoices as $answerChoice) {
//
}
SELECT
*, SUM(num_hr) AS total_hr, attendances.empID AS empid
FROM attendances
LEFT JOIN addsalaryemployees ON addsalaryemployees.empID=attendances.empID
LEFT JOIN positions ON positions.id=addsalaryemployees.empPosition
GROUP BY attendances.empID
ORDER BY addsalaryemployees.empFirstName ASC
I am learning relationships in Laravel php framework and I am trying to build this query
SELECT * FROM users u INNER JOIN link_to_stores lts ON u.id=lts.user_id INNER JOIN stores s ON lts.store_id=s.store_id WHERE lts.privilege = 'Owner'
I built this in Model
Link_to_store.php
public function store()
{
return $this->belongsTo('App\Store');
}
public function user()
{
return $this->belongsTo('App\User');
}
User.php
public function store_links()
{
return $this->hasMany('App\Link_to_store');
}
Store.php
public function user_links()
{
return $this->hasMany('App\Link_to_store');
}
I tried this query but this only joins user and link_to_store table
$personal_stores = Auth::user()->store_links->where('privilege','=','Owner');
Now I am confused how to join store table too. Can anyone help with this?
Schema is like this
Stores Table
store_id store_name
Users Table
id name
Link_to_stores Table
id store_id user_id privilege
I suppose store_links is actually a pivot table. In this case, you can use belongsToMany(), this will automatically take care of the pivot table.
To do this, in your User model you change the store function to this:
function stores() {
return $this->belongsToMany('App\Store', 'store_links', 'user_id', 'store_id')->withPivot('privilege');
}
Because the primary key of stores is not id, you will have to define this in you Store model with the following line:
protected $primaryKey = 'store_id';
Now to get the stores for a user, you simply call
$stores = Auth::user->stores()->wherePivot('privilege', 'Owner')->get();
I am learning relationships in Laravel php framework and I am trying to build this query
SELECT * FROM users u INNER JOIN link_to_stores lts ON u.id=lts.user_id INNER JOIN stores s ON lts.store_id=s.store_id WHERE lts.privilege = 'Owner'
You are trying to do a join here. You can do a join like this:
$stores = User::join('link_to_stores as lts', 'users.id', '=', 'lts.user_id')->join('stores as s', 'lts.store_id', '=', 's.id')->where('lts.privilege', 'Owner')->get();
But like Jerodev pointed out, it seems like Many to Many relationship might make more sense in your case. The difference is that relationship will actually execute 2 queries (1 for original model, 1 for relationship). It will then attach the related models to the original model (which is extremely handy).
I am trying to implement following join query
SELECT * from users as u
LEFT JOIN `table1` as ou
ON ou.user_id = u.id
LEFT JOIN table2 as o
ON o.id = ou.orid
LEFT JOIN table3 as p
ON o.pra_id = p.id;
with my laravel model so i create a function named alldata() in my user model with following code
public function alldata()
{
return $this
->leftjoin('table1','users.id','=','table1.user_id')
->leftjoin('table2','table1.orid','=','table2.id')
->leftjoin('table3','table2.pra_id','=','table3.id');
}
now when i try to access the data by $gd = User::find(1)->getall() it returns results with all the table
but when i try to acces $gd = User::all()->alldata() it gaves error mathod not found
how can i resolve this
thanks
The User::find(1) function returns an single instance of the object (or NULL if not found).
The User::all() function returns a Collection of all User objects.
You need to create a query then get() the results as follows...
public static function alldata()
{
return self::query()
->leftjoin('table1','users.id','=','table1.user_id')
->leftjoin('table2','table1.orid','=','table2.id')
->leftjoin('table3','table2.pra_id','=','table3.id')
->get();
}
Assuming your your alldata() method is in the User class you can call the function with the following code:
User::alldata();
Laravel has a excellent database relationship system which is most defiantly worth looking at. It would make queries like the one above much simpler...
https://laravel.com/docs/5.1/eloquent-relationships
I'm working with L5 and elequent
My table structure is..
users
id
other field
auctions
id
other field
lots
id
auction_id
other field
lot_user
lot_id
user_id
I want to find auctions for a user.
How can i do this?
$user = User::find($id);
$auctions = $user->auctions();
I have got an idea to do this with eloquent..
$auctions = $user->lots()
->join('auctions','auctions.id','=','lots.id')
->select(['auctions.*'])
->get();
I'm not sure Eloquent is going to be very efficient here, but you could do something like :
In your User(s) class, you need to define a many-many relationship like :
public function lots()
{
return $this->belongsToMany('App\Lot');
}
In your Lot(s) class, you need to define the inverse of a one-to-many relationship like:
public function auctions()
{
return $this->belongsTo('App\Auction')
}
Then, to get Lots for a user, you'd do something like :
$user->lots();
To get auctions, you'd need to loop over lots and call $lot->auctions() for each one, and then filter by id to get the unique auctions.
This is a case where it would probably be easier to use the DB facade to built a query instead of just trying to use Eloquent.
About DB facade.
Raw query will looks like this:
SELECT * FROM auctions AS a
INNER JOIN lots AS l ON (l.auction_id = a.id)
INNER JOIN lot_user AS lu ON (lu.lot_id = l.id AND lu.user_id = $findUserId)
GROUP BY a.id
And using query-builder you can do it like this:
DB::table('auctions')
->join('lots', 'lots.auction_id', '=', 'auctions.id')
->join('lot_user', function ($join) {
$join->on('lot_user.lot_id', '=', 'lots.id')
->where('lot_user.user_id', '=', $findUserId);
})
->groupBy('auctions.id')
->get();
I want to create join query for multiple models with separate (model) conditions.
I have create following query :
select * from studentinformation as s left join studentattandence a on s.id =
a.studentid where s.PersonalFirstName='Kathi' and s.PersonalLastName='irfan'
and s.Age='2' and s.gender ='Male' and s.StudentCourse='1' and
s.GuardianFirstName='test' and s.GuardianLastName = 'test' and a.date
BETWEEN '2015-02-01' AND '2015-02-07'
Table of studentinformation model name is "StudentAdmissionModel".
Table of studentattandence model name is "StudentAttandenceModel".
How can i do this laravel Eloquent ORM.
You would need to declare a relationship between the two in the StudentAdmissionModel, which would look something like this:
class StudentAdmissionModel extends Eloquent {
public function attendance()
{
// Assuming a one-to-one relationship
return $this->hasOne('StudentAttandenceModel','studentid');
}
}
Then you would be able to use the whereHas() function to query the relationship:
$admissions = StudentAdmissionModel::where('PersonalFirstName','=','Kathi')
->where('PersonalLastName','=','irfan')
->where('Age','=','2')
->where('gender','=','Male')
->where('StudentCourse','=','1')
->where('GuardianFirstName','=','test')
->where('GuardianLastName ','=','test')
->whereHas('attendance',function($q)
{
$q->whereBetween('date', array('2015-02-01','2015-02-07'));
})
->with('attendance') // Optional eager loading, but recommended
->get();
And you would be able to access the fields like this:
foreach( $admissions as $admission){
echo $admission->gender;
// or
echo $admission->attendance->date;
}