Reputation: 23891
I got this error message when trying to join multiple tables
Illuminate \ Database \ QueryException (42000)
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'users' (SQL: select * from `prescriptions` inner join `doctors` on `prescriptions`.`doctor_id` = `doctors`.`id` inner join `users` on `doctors`.`user_id` = `users`.`id` inner join `patients` on `prescriptions`.`patient_id` = `patients`.`id` inner join `users` on `patients`.`user_id` = `users`.`id` inner join `pharmacies` on `prescriptions`.`patient_id` = `pharmacies`.`id` inner join `users` on `pharmacies`.`user_id` = `users`.`id` where `prescriptions`.`pharmacy_id` = 1)
My code is like this
$prescriptions = DB::table('prescriptions')
->join('doctors', 'prescriptions.doctor_id', '=', 'doctors.id')
->join('users', 'doctors.user_id', '=', 'users.id')
->join('patients', 'prescriptions.patient_id', '=', 'patients.id')
->join('users', 'patients.user_id', '=', 'users.id')
->join('pharmacies', 'prescriptions.patient_id', '=', 'pharmacies.id')
->join('users', 'pharmacies.user_id', '=', 'users.id')
->where('prescriptions.pharmacy_id',$pharmacy->id)
->get();
My ERD diagram
Upvotes: 1
Views: 2294
Reputation: 16333
As others have correctly pointed out, the problem is that you've joined in the users
table three times but since they have not been aliased, your database is unable to distinguish which table you mean when you try to use it in any way. The solution would be to alias each users
table when you join them. For example:
$prescriptions = DB::table('prescriptions')
->join('doctors', 'prescriptions.doctor_id', '=', 'doctors.id')
->join('users as du', 'doctors.user_id', '=', 'du.id')
->join('patients', 'prescriptions.patient_id', '=', 'patients.id')
->join('users as pu', 'patients.user_id', '=', 'pu.id')
...
->get([
'du.name as doctor_name',
'pu.name as patient_name',
'prescriptions.description as description'
]);
To grab the doctor's name for example:
foreach ($prescriptions as $prescription) {
echo $prescription->doctor_name;
}
However, I would suggest doing this with Eloquent instead:
$prescriptions = Prescription::where('pharmacy_id', $pharmacyId)
->with('patient', 'patient.user', 'doctor', 'doctor.user');
This will effectively run one query to select all prescriptions by the given pharmacy_id
and then it will run subsequent queries to eagerly load in the associated patients (and their associated users) and those doctors (and their associated users).
If you don't need to load the pharmacy name or any other information about the pharmacy or its associated user, then you needn't bother load them in. If you do, it's as simple as following the above format and adding them to the ->with()
which will result in them being eager loaded.
After doing the above, you can access a patient's name like this:
foreach ($prescriptions as $prescription) {
echo $prescription->patient->user->name;
}
This of course assumes you have your relations all correctly set up.
Upvotes: 3
Reputation: 1672
this is because you're using the same alias for 3 joins .. this will do:
$prescriptions = DB::table('prescriptions')
->leftJoin('doctors', function($join){
$join->join('users as a', 'doctors.user_id', '=', 'a.id');
})
->leftJoin('patients', function($join){
$join->join('users as b', 'patients.user_id', '=', 'b.id');
})
->join('pharmacies', function($join){
$join->join('users as c', 'pharmacies.user_id', '=', 'c.id');
})
->where('prescriptions.pharmacy_id',$pharmacy->id)
->get();
Upvotes: -1