Laravel query to join different tables based on a condition - mysql

How to join multiple tables based on a condition.
I have 3 tables.
Transactions table
advertisement table
offerrequests table
Transaction table has relation with advertisement and offerrequests table by the fields - is_sell and post_id
if is_sell = 1 then
// post id is id in advertisement table
if is_sell is 0 then
// post id is id in offerrequests table
column country is only presnt in advertisemnt and offerrequests table.
so i need to join the tables to get country for each transaction
I got the result using mysql query like :
SELECT transactions.id , IF( transactions.is_sell = '1', advertisements.country, offerrequests. country ) AS country
FROM transactions
LEFT JOIN advertisements ON ( advertisements.id = transactions.post_id )
LEFT JOIN offerrequests ON ( offerrequests.id = transactions.post_id );
Can anyone help me to get the laravel query corresponding to same

You can use
$transactions = DB::table('transactions')
->select('transactions.id', DB::raw("IF(transactions.is_sell = '1', advertisements.country, offerrequests.country) as country"))
->leftJoin('advertisements', function ($join) {
$join->on('advertisements.id', '=', 'transactions.post_id');
})
->leftJoin('offerrequests', function ($join) {
$join->on('offerrequests.id', '=', 'transactions.post_id');
})
->get();

Related

How to Laravel Mysql fetch data from database using multiple table join

This is my data retrieving query:
$admin_students=DB::select("select students.*,application_record.*,gender_record.*,
application_record.id as app_primary_id,application_record.status as app_status from students
left join application_record on application_record.student_id=students.id
left join application_record on application_record.gender_record_id=gender_record.name");
Table structure
Table 1 = application_record - > id, name, status, gender_record_id, ....
Table 2 = gender_record - > id, name
Now how can I return the Gender Name using the Gender Record ID which is the primary key for "Table 2"?
DB:: table('students')
->leftjoin('application_record, 'students.id','=' , 'application_record.student_id' )
->leftjoin('gender_record','application_record.gender_record_id','=','gender_record.id')->select('students.*',' application_record.*,
'gender_record.*,)->get();

Laravel: get the most purchases product for current user

I have 3 tables here (order_lists, order_details, products)
Table order_lists contain the following user_id
Table order_details contain the following order_lists_id product_id
Table products contain all the products details.
the three tables are related to each others in models.
I need to select the most purchases items from table order_details based this user_id.
I made very basic Eloquent query which will select 6 products for this user but stuck on how to get the most purchases product
$mostPurchases = OrderList::where( 'user_id', Auth::id() )
->with( [
'orderDetails' => function ( $query ) {
$query->with( 'productId' );
}
] )->take( 6 )->get();
in order_details I need to count the user most purchases product.
UPDATE
As #party-ring suggest to use DB::raw query this is the final query looks like.
$usId = Auth::id();
$mostPurchases = DB::select( DB::raw( 'SELECT product_id, count(*) from order_details
LEFT JOIN order_lists ON order_details.order_lists_id = order_lists.id
WHERE order_lists.user_id = ' . $usId . '
group by product_id
order by count(*) DESC
LIMIT 6' ) );
Update
DB::table( 'products' )
->where( 'soft_delete', '!=', 1 )
->leftJoin( 'order_details', 'products.id', '=', 'order_details.product_id' )
->select( DB::raw( 'count(*) as pro_count, product_id' ) )
->leftJoin( 'order_lists', 'order_details.order_lists_id', '=', 'order_lists.id' )
->where( 'order_lists.user_id', '=', $usId )
->orderBy( 'pro_count', 'DESC' )
->groupBy( 'product_id' )
->take( 6 )
->get();
but still I got only the pro_count, and product_id
{
"pro_count": 22,
"product_id": 733
},
{
"pro_count": 15,
"product_id": 85
},
I need the product details within the response.
I would go about this by using join and DB::raw as I have found it can be more efficient than Eloquent when dealing with large datasets opposed to a function query - also I find it a little easier to build up my queries in this way.
select(DB::raw('SELECT product_id, count(*) from order_details
LEFT JOIN `order_lists` ON order_details.order_lists_id = order_lists.id
WHERE order_lists.user_id = :authUser
group by product_id
order by count(*) DESC
LIMIT 6', ['authUser => Auth::id()']);
You might need to play around with this a little as I don't know if you will need to specify the table names in your query.
This is adding together your order_lists and order_details tables, limiting it to that of the auth user, grouping it by the product id, ordering it by the count of those product purchases for the user and limiting it to 6 results.

Mysql/Laravel : Using left join to fetch latest created at date of any employee

I'm trying to get all sections and their latest created_at using left join
I'm using below query
select es.*, sul.created_at as created_at from section as es
left join section_update_logs as sul on es.id = sul.section_id
where sul.emp_id = 3
group by es.id
order by es.id, sul.created_at asc;
the obvious output of the query is only show that records where emp_id is 3, but i want all the records of section table, if there is no employee record in section_update_logs there should be a null/empty created_at.
Desired output is :
all rows of table section
created_at date if sul.section_id = section.id and emp_id = of particular employee.
Laravel Query :
$result = DB::table("section as es")
->select('es.*', 'sul.created_at')
->leftJoin('section_update_logs as sul', 'es.id', '=', 'sul.section_id')
->orderBy('es.weight')
->orderBy('sul.created_at')
->orWhere('sul.emp_id', $emp_id)
->groupBy('es.id')
->get();
Please help
You can add a closure to the leftJoin function to add more conditions.
$result = DB::table("section as es")
->select('es.*', DB::raw('MAX(sul.created_at)'))
->leftJoin('section_update_logs as sul', function ($join) use ($emp_id) {
$join->on('es.id', '=', 'sul.section_id')
->where('sul.emp_id', $emp_id);
})
->orderBy('es.weight')
->orderBy('sul.created_at')
->groupBy('es.id')
->get();
This way, the filter on sul.emp_id is only validated when a relation is found.
To get the same result with your sql query, add a second condition to your join using AND:
select es.*, MAX(sul.created_at) as created_at from section as es
left join section_update_logs as sul on es.id = sul.section_id AND sul.emp_id = 3 -- HERE
group by es.id
order by es.id, sul.created_at asc;
you need to use first since you are to display the result of a particular employee
$search = $request->input('id');
$data['result'] = DB::table("section")
->where('emp_id', $search)
->leftJoin('section_update_logs', 'section.id', '=', 'section_update_logs.section_id')
->orderBy('section_update_logs.created_at','desc')
->first();
return view('viewblade', $data)
on your view
{{ $result ->name }}
...

optimise Yii2 MYSQL query

I need to optimise my code.it works but takes time and sometimes timeouts.
Objective selected columns from table 1 and table 2 must be combined in another table. duplicates are not allowed in the new table. TIA
$modelsc=Customers::find()->select('customer_id')->all();
$modelsp = Product::find()->select('product_no')->all();
foreach($modelsc as $modelc) {
$user = $connection->createCommand(
'SELECT product_no as product_no,:cust_no as fkcustomer_id
FROM product AS p
WHERE NOT EXISTS( SELECT pc.fkproduct_no
FROM
productcustomer AS pc
WHERE
pc.fkproduct_no = p.Product_no AND fkcustomer_id = :cust_no)');
$user->bindValue(':cust_no', $modelc->customer_id);
$modelsx = $user->queryAll();
Yii::$app->db->createCommand()->batchInsert('productcustomer', [ 'fkproduct_no', 'fkcustomer_id'], $modelsx)->execute(); }
looking to your code you could avoid the not exists clause an try using a left join checkn for null on pc.fkproduct_no
SELECT product_no as product_no,
:cust_no as fkcustomer_id
FROM product AS p
LEFT JOIN productcustomer AS pc ON pc.fkproduct_no = p.Product_no
AND fkcustomer_id = :cust_no
WHERE pc.fkproduct_no is null
Anyway be sure you have proper index on the column where of join condition
for table products an index on column Product_no
for table productcustomer a composite index on (fkcustomer_id, fkproduct_no)

How to join with three rows from table one with second table in laravel

in laravel 5.6 i want to fetch data from database with join query in my case i want to join multiple tables such as employee, designation, booking, vehicles when i use join it shows following errors(SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'employees' (SQL: select * from bookings inner join vehicles on bookings.vehicle_id = vehicles.vehicle_id inner join employees on bookings.driver_id = employees.id inner join employees on bookings.conductor_id = employees.id inner join employees on bookings.helper_id = employees.id inner join designations on employees.desg_id = designations.desc_id)) i google it several times but i could not find any solutions how can i solve this problems your efforts will be appreciate in this case thanks in advance.
in my laravel model Booking
public function get_booking(){
$booking = DB::table('bookings')
->join('vehicles', 'bookings.vehicle_id', '=', 'vehicles.vehicle_id')
->join('employees', 'bookings.driver_id', '=', 'employees.id')
->join('employees', 'bookings.conductor_id', '=', 'employees.id')
->join('employees', 'bookings.helper_id', '=', 'employees.id')
->join('designations', 'employees.desg_id', '=','designations.desc_id')
->get();
return $booking;
You have to use table aliases and join designations three times:
->join('employees as e1', 'bookings.driver_id', '=', 'e1.id')
->join('employees as e2', 'bookings.conductor_id', '=', 'e2.id')
->join('employees as e3', 'bookings.helper_id', '=', 'e3.id')
->join('designations as d1', 'e1.desg_id', '=','d1.desc_id') -
->join('designations as d2', 'e2.desg_id', '=','d2.desc_id')
->join('designations as d3', 'e3.desg_id', '=','d3.desc_id')
You also have to use column aliases (depending on your required columns):
->get(['bookings.*', 'vehicles.*', 'e1.name as driver_name',
'e2.name as conductor_name', 'e3.name as helper_name']);