How to join tables with more than one attribute match? - php

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();

Related

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();

join with multiple conditions in Laravel

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();

How to create SQL Join Statement in Laravel Controller

I have two table customer_id namely tbl_customer and tbl_stocks connected on the same database. My logic about this problem is JOIN sql statement.
This is for Laravel and MySQL, so far i've tried this on PHP and is working fine but when I implement it on laravel it is not working i wonder why?
here is my code in PHP and want to convert it to laravel but I dont know where to put? will i put it in the View or in the Controller
$query = "SELECT c.*, s.* FROM tbl_customer c JOIN tbl_stock s ON s.customer_id = c.customer_id AND c.customer_id = 1";
Controller
$data = DB::table('tbl_customer')
->join ...... //Im not sure about this
->select .... // neither this
->get();
print_r($data)
Model
I have no codes on my model
Routes
Route::get('/admin/shopcontrol', 'Admin\ShopsController#testquery');
I expect a result of fetching or getting the query or result of the values in just a simple echo and the fetch join is connected
Have you checked the Laravel site?
https://laravel.com/docs/5.7/queries#joins
It has a demonstration you could use to reorganize your code.
As it follows below from the site.
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. Of course, as you can see, you can 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();
You may find more information there if it suits you.
Try this:
$data = DB::table('tbl_customer')
->join('tbl_stock', 'customer_id', '=', 'tbl_customer.customer_id')
->select('tbl_customer.*', 'tbl_stock.*')
->where('customer_id', '=', 1)
->get();

Laravel 5: Native SQL to Query Builder

I am trying to join 2 tables on Laravel 5 and have to use Query Builder. I have already got the sql for it but i am not able to convert it to Query Builder syntax. SQL is below
SELECT v.id, r.full_name, b.full_name, s.full_name
FROM vehicles v
LEFT JOIN clients r ON v.representive_client_id = r.id
LEFT JOIN clients b ON v.buyer_client_id = b.id
LEFT JOIN clients s ON v.seller_client_id = s.id
and what i tried is
$query_result = DB::table('vehicles')
->selectRaw($query)
->leftJoin('clients', 'vehicles.representive_client_id', '=', 'clients.id')
->leftJoin('clients', 'vehicles.buyer_client_id ', '=', 'clients.id')
->leftJoin('clients', 'vehicles.seller_client_id ', '=', 'clients.id')
->paginate(30);
The problem is i dont know how to use AS caluse for Query Builder as i need to retrive 3 different types of full_name columns from vehicles table.Anybody can help me about how to write it in a proper Query Builder syntax ?. Any help would be appreciated.
You can use aliases with select columns and tables as well as joins, because the Query Builder will know to quote them correctly. So you can do this without any problems:
$query_result = DB::table('vehicles v')
->select('v.id', 'r.full_name as r_name', 'b.full_name as b_name', 's.full_name as s_name')
->leftJoin('clients r', 'vehicles.representive_client_id', '=', 'r.id')
->leftJoin('clients b', 'vehicles.buyer_client_id ', '=', 'b.id')
->leftJoin('clients s', 'vehicles.seller_client_id ', '=', 's.id')
->paginate(30);
Of course, you can use whatever aliases you want for the selected columns. Actually one of the examples in the Query Builder Selects Documentation uses aliases: email as user_email.
To check the SQL query generated by the Query Builder you can use the toSql method. So in your case instead of ->paginate(30) you can have ->toSql(), which will return a string with the SQL generated by the Query Builder, which you can compare to your raw query and see if it matches.

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