join with multiple conditions in Laravel - php

I'm trying to join two tables using more than one condition. The following query is not working because of the second join condition.
$all_update = DB::table('posts as p')
->join('cprefs as c','p.qatype', '=', 'c.qatype')
->where('c.wwide', '=', 'p.wwide') //second join condition
->where('c.user_id', $u_id)
->where('p.arank', 1)
->get();

The where() functions expects the last parameter to be a parameter where as you are passing in a column name.
To compare two columns you should use the whereColumn method.
With that in mind, you could also write your code like below:
$all_update = DB::table('posts as p')
->join('cprefs as c','p.qatype', '=', 'c.qatype')
->whereColumn('c.wwide', '=', 'p.wwide') //second join condition
->where('c.user_id', $u_id)
->where('p.arank', 1)
->get();
However, this would only work properly if the the join is an INNER JOIN which is true in your case.
The correct method to add multiple join clauses is as below
$all_update = DB::table('posts as p')
->join('cprefs as c', function($q) {
$q->on('p.qatype', '=', 'c.qatype')
->on('c.wwide', '=', 'p.wwide'); //second join condition
})
->where('c.user_id', $u_id)
->where('p.arank', 1)
->get();
Just use this one.

You need the keyword join to use multiple join condition. Irrespective of table.
$all_update = DB::table('posts as p')
->join('cprefs as c','p.qatype', '=', 'c.qatype')
->join('cprefs as c2','p.wwide', '=', 'c2.wwide') //second join condition
->where('c.user_id', $u_id)
->where('p.arank', 1)
->get();

Related

Laravel join query not working when passing a variable

I want to execute a join statment in laravel by passing a php varaiable,Bit its not working when passing a varibale. Following is my code
$loc_services = Clinic::select('*')
->join('locations', 'locations.clinicID', '=', 'clinics.clinicID')
->join('location_services', 'location_services.locationID', '=', 'locations.locationID')
->join('services', 'services.serviceID', '=', $services_id)
->get();
I tried to execute it as statment and got the following
select * from `clinics` inner join `locations` on `locations`.`clinicID` = `clinics`.`clinicID` inner join `location_services` on `location_services`.`locationID` = `locations`.`locationID` inner join `services` on `services`.`serviceID` = `10`
When i directly executed it in phpmyadmin it returns fllowing error
Column not found: 1054 Unknown column '10' in 'on clause', i found that error is triggering because `10` is inside `''` quotes, how can i execute this
You have to pass $services_id in where cloud not in join on
$loc_services = Clinic::select('*')
->join('locations', 'locations.clinicID', '=', 'clinics.clinicID')
->join('location_services', 'location_services.locationID', '=', 'locations.locationID')
->join('services', 'services.serviceID', '=', 'clinics.services_id')//service_id column in Clinic
->where('services.serviceID',$services_id)
->get();
The third parameter in join will be treated as column. If you want to join the column with a specific value, you can use closure like this:
$loc_services = Clinic::select('*')
->join('locations', 'locations.clinicID', '=', 'clinics.clinicID')
->join('location_services', 'location_services.locationID', '=', 'locations.locationID')
->join('services', function($join) use ($service_id) {
$join->where('services.serviceID', $service_id);
})
->get();
The Raw sql will be:
inner join `services` on `services`.`serviceID` = 10

Query using Eloquent Laravel using "as"

How do you know the other code to get this query in laravel using eloquent?
$variable_value= DB::select(
'SELECT
sv.VARIABLE_NAME as sv_variable_name, sv.TYPE as sv_type, sv.ADDRESS as sv_address, sv.VALUE as sv_value,
ms.VARIABLE_NAME as ms_variable_name, ms.TYPE as ms_type, ms.ADDRESS as ms_address, ms.VALUE as ms_value
FROM MASTER_VARIABLES ms
JOIN SLAVE_VARIABLES sv ON ms.SLV_ADDRESS=sv.ID_VARIABLE'
);
Thank you for your help, guys!
It's all in the documentation. Give it a read?
# Selects
Specifying A Select Clause
You may not always want to select all columns from a database table. Using the select method, you can specify a custom select clause for the query:
$users = DB::table('users')->select('name', 'email as user_email')->get();
# Joins
Inner Join Clause
The query builder may also be used to write join statements. To perform a basic "inner join", you may use the join method on a query builder instance. The first argument passed to the join method is the name of the table you need to join to, while the remaining arguments specify the column constraints for the join. You can even join to multiple tables in a single query:
$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();
$query = DB::table('MASTER_VARIABLES as ms')
->select(
'sv.VARIABLE_NAME as sv_variable_name',
'sv.TYPE as sv_type',
'sv.ADDRESS as sv_address',
'sv.VALUE as sv_value',
'ms.VARIABLE_NAME as ms_variable_name',
'ms.TYPE as ms_type',
'ms.ADDRESS as ms_address',
'ms.VALUE as ms_value'
)
->join('SLAVE_VARIABLES as sv', 'ms.SLV_ADDRESS', '=', 'sv.ID_VARIABLE')
->get();

How to join tables with more than one attribute match?

I am trying to turn my raw sql into laravel query builder and I encounter difficulty on how to join multiple tables using with many attributes match.
In this case, I want to join the table jr_h and jr_d with three attributes match (book,p_seq and staff_code) rather than one (book).
Raw sql:
$sql = "select from_time,to_time,t.staff_code,s.name_t as staff_name,t.book,t.p_code,t.p_seq,p.hrs1,s.img_file,
t.hrs_work,p.sharing_cnt as hrs_work, t.hrs_ot as hrs_ot from jr_d as t
inner join jr_h as p on(t.book=p.book and t.p_seq=p.p_seq and t.staff_code=p.staff_code)
inner join astaff as s on(t.staff_code=s.staff_code) ";
Laravel query builder:
$jr_d = DB::table('jr_d')
->join('jr_h', 'jr_d.book', '=', 'jr_h.book')
->join('astaff', 'jr_d.staff_code', '=', 'astaff.staff_code')
->select('jr_h.*','jr_d.*','astaff.*','astaff.name_t as staff_name')
->where('jr_d.ref_group','=','E')
->get();
and also want to know if there is a way to make the query faster since it has a lot of data in the tables.
Laravel joins with multiple conditions:
$results = DB::table('jr_d')
->select('jr_h.*','jr_d.*','astaff.*','astaff.name_t as staff_name')
->join('jr_h', 'jr_d.book', '=', 'jr_h.book')
->join('jr_h as p', function($query){
$query->on('t.book','=', p.book');
$query->on('t.p_seq','=', 'p.p_seq');
$query->on('t.staff_code', '=', 'p.staff_code');
})
->where('jr_d.ref_group','=','E')
->get();
`
Try this:
// ...
->join('jr_h p', function($join) {
$join->on('t.book', '=', 'p.book');
$join->on('t.p_seq', '=', 'p.p_seq');
// ... more conditions
});
Try this.
$jr_d = DB::table('jr_d')
->join('jr_h', 'jr_d.book', '=', 'jr_h.book')
->join('astaff', 'jr_d.staff_code', '=', 'astaff.staff_code')
->select('*','astaff.name_t as staff_name')
->where('jr_d.ref_group','=','E')
->get();

Laravel 5.4 query builder having issues with groupBy

I'm trying to convert this query to query builder in Laravel 5.4:
SELECT
oc.id,
oc.name,
oat.user_id,
p.first_name,
p.last_name
FROM
oauth_clients oc
LEFT JOIN oauth_access_tokens oat ON oc.id = oat.client_id
JOIN users u on u.id = oat.user_id
JOIN people p on p.id = u.person_id
WHERE oc.revoked = false AND oc.password_client = true
GROUP BY oc.id, oat.user_id
And getting this error barf: Argument 1 passed to Illuminate\Database\Connection::prepareBindings() must be of the type array, string given, called in /var/www/html/source/luniverse/vendor/laravel/framework/src/Illuminate/Database/Connection.php on line 648 and defined
This is my attempt at it (one of many):
$tokens = DB::select('oc.id','oc.name','oat.user_id','p.first_name','p.last_name')
->from('oauth_clients as oc')
->leftJoin('oauth_access_tokens as oat', 'oc.id', '=', 'oat.client_id')
->join('users as u', 'u.id', '=', 'oat.user_id')
->join('people as p', 'p.id', '=', 'u.person_id')
->where('oc.revoked', '=', 'false')
->where('oc.password_client', '=', 'true')
->groupBy('oc.id')
->groupBy('oat.user_id')
->get();
The database config is set to strict mode, but that doesn't exactly seem to explain that particular error. The raw query runs fine in a DB gui.
Change the groupby code like
$tokens = DB::select('oc.id','oc.name','oat.user_id','p.first_name','p.last_name')
->from('oauth_clients as oc')
->leftJoin('oauth_access_tokens as oat', 'oc.id', '=', 'oat.client_id')
->join('users as u', 'u.id', '=', 'oat.user_id')
->join('people as p', 'p.id', '=', 'u.person_id')
->where('oc.revoked', '=', 'false')
->where('oc.password_client', '=', 'true')
->groupBy('oc.id','oat.user_id')
->get();
DB::select() executes a query, you have to use DB::table():
DB::table('oauth_clients as oc')
->select('oc.id','oc.name','oat.user_id','p.first_name','p.last_name')

Eloquent - join clause with string value rather than column heading

I have a question regarding join clauses in Eloquent, and whether you can join on a string value rather than a table column.
I have the code below querying a nested set joining parent/child records in a table 'destinations' via a table 'taxonomy'.
The second $join statement in the closure is the one causing an issue; Eloquent assumes this is a column, when I would actually just like to join on t1.parent_type = 'Destination' - ie, t1.parent_type should = a string value, Destination.
$result = DB::connection()
->table('destinations AS d1')
->select(array('d1.title AS level1', 'd2.title AS level2'))
->leftJoin('taxonomy AS t1', function($join) {
$join->on('t1.parent_id', '=', 'd1.id');
$join->on('t1.parent_type', '=', 'Destination');
})
->leftJoin('destinations AS d2', 'd2.id', '=', 't1.child_id')
->where('d1.slug', '=', $slug)
->get();
Is it possible to force Eloquent to do this? I've tried replacing 'Destination' with DB::raw('Destination') but this does not work either.
Thanking you kindly.
Another best way to achieve same is :
$result = DB::connection()
->table('destinations AS d1')
->select(array('d1.title AS level1', 'd2.title AS level2'))
->leftJoin('taxonomy AS t1', function($join) {
$join->on('t1.parent_id', '=', 'd1.id');
$join->where('t1.parent_type', '=', 'Destination');
})
->leftJoin('destinations AS d2', 'd2.id', '=', 't1.child_id')
->where('d1.slug', '=', $slug)
->get();
Replace your on with where
try using DB::raw("'Destination'")

Categories