join a single table twice in join query - php

I have 3 tables users and meeting table and user_role. In user table I have user_name and user_role fields
and in meeting table I have the column meeting_id assigned_username and created_by_user_name fields and In user_roles table have id and role .
users
user_name role
a 1
b 2
c 3
meeting table
meeting_id assigned_username created_by_user_name
m1 a b
m2 b -
m3 b a
user_roles
id user_role
1 role1
2 role2
3 role3
I want to get the assigned_user_name's user_role and created_by_user_name's user_role in single query. I have tried as
$user=DB::table('meeting')
->leftjoin('users','users.user_name','=','meeting_after_validation.assigned_user_name')
->leftjoin('users as ca','ca.user_name'),'=','meeting_after_validation.created_by_name')
->leftjoin('user_roles','users.user_role','=','user_roles.id')
->leftjoin('user_roles as carole','ca.user_role','=','carole.id')
->whereIn('carole.is',['1','2'])
->select('users.user_name','user_roles.role','carole.role')->toArray();
but getting
Call to a member function whereIn() on array
how to get role of assigned_user_name and created_by_user_name.

You must use get() before you can use toArray() if you want to get the values as an array.
Also, there may be a typo for your whereIn, should it be carole.id?
Here is what the query could look like in SQL:
SELECT
meeting.meeting_id,
users_assigned.user_name as assigned_user,
role_assigned.user_role as assigned_user_role,
users_created.user_name as created_user,
role_created.user_role as created_user_role
FROM meeting
LEFT JOIN users as users_assigned ON meeting.assigned_username = users_assigned.user_name
LEFT JOIN user_roles as role_assigned ON users_assigned.role = role_assigned.id
LEFT JOIN users as users_created ON meeting.created_by_user_name = users_created.user_name
LEFT JOIN user_roles as role_created ON users_created.role = user_roles.id
WHERE role_assigned.id IN (1, 2)
And in Laravel query builder:
$user = DB::table('meeting')
->select([
'meeting.meeting_id',
'users_assigned.user_name as assigned_user',
'role_assigned.user_role as assigned_user_role',
'users_created.user_name as created_user',
'role_created.user_role as created_user_role',
])
->leftJoin('users as users_assigned', 'meeting.assigned_username', '=', 'users_assigned.user_name')
->leftJoin('user_roles as role_assigned', 'users_assigned.role', '=', 'role_assigned.id')
->leftJoin('users as users_created', 'meeting.created_by_user_name', '=', 'users_created.user_name')
->leftJoin('user_roles as role_created', 'users_created.role', '=', 'user_roles.id')
->whereIn('role_assigned.id', [1, 2])
->get()
->toArray();

Related

How to show only allowed wheels type from some tables in Laravel?

I have some tables I need to select only wheels type which allowed at the zone,
this my Laravel query code:
<?php
$wheels = DB::table('wheels')
->join('users', 'users.id', '=', 'wheels.user_id')
->join('wheels_types', 'wheels_types.id', '=', 'wheels.wheels_type_id')
->join('zone_wheels', 'zone_wheels.wheels_id', '=', 'wheels.id')
->leftjoin('zones', function($join){
$join->on('zones.wheels_type_1','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_2','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_3','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_4','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_5','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_6','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_7','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_8','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_9','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_10','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_11','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_12','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_13','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_14','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_15','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_16','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
$join->orOn('zones.wheels_type_17','=','wheels.wheels_type_id'); // i want to join the users table with either of these columns
})
->where('zone_wheels.zone_id', $this->id)
->where('zone_wheels.is_approved', true)
->whereNull('zone_wheels.deleted_at')
->select(
'wheels.id AS wheels_id',
'wheels.user_id AS user_id',
'wheels.name AS name',
'wheels.price AS price',
'users.email AS contact',
'wheels.city AS city',
'wheels.model AS model',
'users.fb_certified AS fb_certified',
'users.paid_certified AS paid_certified',
'wheels_types.name_en AS type',
'wheels.status AS status',
'wheels.zipcode AS zipcode',
'wheels.base_city AS base_city',
'wheels.description AS description')
->orderBy('wheels.updated_at', 'desc')
->paginate(12);
?>
My zone types :
only selected wheels types should be showen at the zone,
I have tables
'wheels' => 'wheels_type_id'
'zones' => 'wheels_type_1' to 'wheels_type_17'
'zone_wheels' => 'wheels_id'
Try str_limit, https://laravel.com/docs/7.x/helpers#method-str-limit
Example:
use Illuminate\Support\Str;
$truncated = Str::limit('The quick brown fox jumps over the lazy dog', 20);
// The quick brown fox...

How to select from a table based on another table's values Eloquent?

I am trying to get the data on some students that are still active. Even tho I have data from inactive students in the same table.
This is the StudentAttendance
This is the StudentClass
This is the Eloquent query that I came up with:
StudentAttendance::
select('student_classes.active', 'student_attendances.student_id', 'student_attendances.classroom_id', 'classrooms.classroom', 'attendance_rules.option')
->join('classrooms', 'classrooms.id', '=', 'student_attendances.classroom_id')
->join('attendance_rules','attendance_rules.id', '=', 'student_attendances.attendance_id')
->join('student_classes', 'student_attendances.student_id', '=', 'student_classes.student_id')
->where('attendance_date', date("Y-m-d"))
->orderBy('classrooms.classroom', 'ASC')
->get();
SQL:
select `student_classes`.`active`, `student_attendances`.`student_id`, `student_attendances`.`classroom_id`, `classrooms`.`classroom`, `attendance_rules`.`option`
from `student_attendances`
inner join `classrooms` on `classrooms`.`id` = `student_attendances`.`classroom_id`
inner join `attendance_rules` on `attendance_rules`.`id` = `student_attendances`.`attendance_id`
inner join `student_classes` on `student_attendances`.`student_id` = `student_classes`.`student_id`
where `attendance_date` = '2020-02-11'
order by `classrooms`.`classroom` asc
Now my Eloquent query results into this:
As you can see the student_id 22 with the classroom_id of 2 is inactive but it appears to be inactive once and the rest active. If I remove the student_classes join I won't get all the repeated results.
The goal is to display all the attendances of today where the student is active (active=1) in the StudentClass even if I query in the StudentAttendance.
You will want to scope your join to student_classes to only look at active records.
You can do this by using a callback in your join method:
->join('student_classes', function ($join) {
$join->on('student_attendances.student_id', '=', 'student_classes.student_id')
->on('student_classes.classroom_id', '=', 'student_attendances.classroom_id')
->where('student_classes.active', 1);
})
This is covered under the 'Advanced Join Clauses' in the Query Builder docs - https://laravel.com/docs/5.8/queries#joins

Laravel complex query

I have the following tables:
Dishes
id
name
Customers
id
name
Ingredients
id
name
Dishes_Ingredients (table to put in relation dishes and ingredients)
id
dish_id
ingredient_id
Customers_Allergic_Ingredients (customers are allergic to certain ingredients)
id
customer_id
ingredient_id
Customers_Intolerance_Ingredients (customers are intolerant to certain ingredients)
id
customer_id
ingredient_id
I need to get the following information from the database: for a given customer_id, I want to retrieve all the dishes which the customer is not allergic to and not intolerant to, using Laravel Query Builder.
This is what I tried so far:
$dishes = DB::table('dishes')
->join('dishes_ingredients', 'dishes.id', '=', 'dishes_ingredients.dish_id')
->join('customers_allergic_ingredients', 'dishes_ingredients.ingredient_id', '<>', 'customers_allergic_ingredients.ingredient_id')
->join('customers_intolerance_ingredients', 'dishes_ingredients.ingredient_id', '<>', 'customers_intolerance_ingredients.ingredient_id')
->where('customers.id', 1)
->select('dishes.id', 'dish_translations.name')
->get();
Try to use Laravel Eloquent: Relationships
this will save your time & your code will be more simply....
https://laravel.com/docs/5.2/eloquent-relationships
I don't know Laravel but if you just want to solve your problem:
SELECT *
FROM Dishes d
WHERE d.id NOT IN
(
SELECT DISTINCT dish_id
FROM Dishes_Ingridients
WHERE ingredient_id IN
(SELECT DISTINCT ingredient_id FROM Customers_Allergic_Ingredients cai WHERE cai.customer_id = ?)
OR
ingredient_id IN
(SELECT DISTINCT ingredient_id FROM Customers_Intolerance_Ingredients cii WHERE cii.customer_id = ?)
)
$dishes = DB::table("dishes AS a")
->select(array("a.*" ))
->join("dishes_ingredients AS b", "a.id", "b.dish_id")
->join("Customers_Allergic_Ingredients AS c", "b.id", "=", "c.ingredient_id")
->where("c.customer_id", "!=", $customer_id)
->groupBy("a.id")
->get();
This will give you all dishes made with ingredients that the customer is not allergic to

Laravel - Getting data from few tables (joining and ordering)

I'm creating a ranking of players badges and I'm stuck with db query.
Tables:
user(id), club(id), club_user(user_id, club_id), badges(user_id)
I would like to get list of all users from specified club (for example club.id = 1) with amount of badges they have. Results should be ordered by number of badges.
How to create that kind of db query? Is it possible with Eloquent?
Should it be made with db::table and join?
Table user
id|name
1|John
2|Robert
3|Kate
Table club
id|name
1|Sunshine Club
2|Example Club
Table club_user
user_id|club_id
1|1
2|1
3|2
Table bagdes
id|name|user_id|club_id
1|Champion|1|1
2|Some badge|1|1
3|example|2|1
4|Gold Badge|3|2
so if I would like to get ranking of users from club 1, ordered by badge count.
I should get:
name|number of badges
John|2 (badges)
Robert|1 (badge)
Kate is not it this club.
Try this
select user.name ,user.id as userid , (select count(bagdes.id) from
bagdes where user_id= userid)
as total_badges from user inner join club_user on
user.id = club_user.user_id where club_user.club_id = 1
You will get your output.
Finally I made it with this DB::table query:
$users = DB::table('users')
->select('users.name', DB::raw('count(*) as badges'))
->join('badges', 'badges.user_id', '=', 'users.id')
->where('badges.club_id', 1)
->groupby('users.id')
->orderBy('badges', 'DESC')
->get();

QueryBuilder: Sum values of a pivot table

I'm new on Laravel & Eloquent. I have Users, Products and Votes tables on my DB. Users can vote (0 to 5) on products, so it is a "many to many" relationship, with the Votes table acting like a pivot:
Users: id, name, email, password
Products: id, name, model, brand
Votes: user_id, product_id, vote
I mapped this schema like this:
// User model:
public function product_votes()
{
return $this->belongsToMany('App\Product', 'votes')->withPivot('vote');
}
// Product model:
public function product_votes()
{
return $this->belongsToMany('App\User', 'votes')->withPivot('vote');
}
So John can vote 5 on product X and 0 on product Y. Bob can vote 2 on product X, 3 on product Y, and so on...
I'm trying to query all products, with the sum of votes of each one of them. Something like:
SELECT p.*, (SUM(v.vote) / COUNT(*)) as votes FROM products p INNER JOIN votes v on v.product_id = p.id GROUP BY p.id
How can I do that with QueryBuilder? My mapping is right?
The following will do the trick:
Product::select('products.*', DB::raw('SUM(vote)/COUNT(*) as votes'))
->join('votes', 'votes.product_id', '=', 'products.id')
->groupBy('products.id')
->get();
You can see the query that will be run by calling toSql() instead of get().

Categories