Laravel append data count to database object - php

Hello i have this function
public function readData(){
$TableB1 = \DB::table('users')
->join('group_user', 'users.id', '=', 'group_user.user_id')
->join('groups', 'groups.id', '=', 'group_user.group_id')
->join('meetings', 'users.id', '=', 'meetings.owned_by_id')
->select(
'users.name as name',
'group_user.user_id as id',
'groups.name as groupname',
)
->get();
foreach ($TableB1 as &$data){
$meetings = \DB::table('meetings')
->where('company_id', 1)->where('owned_by_id', $data->id)
->where(\DB::raw('MONTH(created_at)'), Carbon::today()->month);
echo $meetings->count();
}
return $TableB1;
}
i retrieve some data from database and return them and use AJAX Call to use them later
The problem is i have a table called users and table called meetings
i want to know how many meetings every user done everyday
so to do this i made a for each to take the user_id and use it to get the count
of meetings done by each user
for example in meetings table i have a owned_by_id field which have the user_id
so what the code does if it found for example if owned_by_id(6) repeated in
meetings table 4 times it will return 4
but this is what i get in the browser
instead what i want to get is something like this
im using Laravel 5.7 and sorry i know my question is unclear this is the 1st time i have ever asked question on stackoverflow
Image

If you want count of meetings then you may use laravel eloquent method with is: withCount();
Like this:
$users = User::with('meetings')->withCount('meetings')->get();
If you will do this then you will get meetings_count with your user object.
And if you have still any doubt you may refer following link:
https://laravel.com/docs/5.8/eloquent-relationships
Thnak you!

You could add a new column in the select() using the COUNT SQL statement:
->select(
'users.name as name',
'group_user.user_id as id',
'groups.name as groupname',
\DB::raw('(
SELECT COUNT(meetings.id) FROM meetings GROUP BY meetings.owned_by_id
) as meetings')
)

Related

Add join filter in Laravel Eloquent

I am a novice in Laravel.
I want to add a filter join through Laravel Eloquent model.
I have below relationship
user belongs to city
user has one restaurant
restaurant has many jobs
Now I want to fetch all jobs with a filter of city.
I tried couple of ways, but ended up in error, like:
$jobs = Job::where("date_time", ">=", $currentDate)->where("city.id", 50)->whereIn('job_status', ['upcoming', 'active'])->orderBy('start_date_time', 'desc')->get();
and the below one
$jobs = Job::with(['restaurant'])->where("date_time", ">=", $currentDate)->where("city.id", 50)->whereIn('job_status', ['upcoming', 'active'])->orderBy('start_date_time', 'desc')->get();
So, here how can I add join from job -> restaurant -> user -> city?
Thanks
Assuming you have city_id in your table
$jobs = DB::table('jobs')->with('restaurant')
->join('users', 'users.id', '=', 'restaurant.user_id')
->join('cities', 'users.id', '=', 'cities.user_id')
->where("table_name.date_time", ">=", $currentDate)
->where("cities.id", 50)
->whereIn('job_status', ['upcoming', 'active'])
->orderBy('table_name.start_date_time', 'desc')->get();
I have edited my answer hope it helps. If not please post your errors and table structure.
You can read about joins here: https://laravel.com/docs/6.x/queries#joins

Laravel query join 1 table in 2 tables at single query

I have a complex query and it works, now i need to join users table and get 2 different value of it based on 2 different tables here is where things messed up.
Code
I have commented issue part as well as data that should be returned
$datas = DB::table('projects')
->orderBy('projects.id', 'desc')
->join('customers', 'projects.customer_id', '=', 'customers.id')
->leftjoin('project_schedules', 'projects.id', '=', 'project_schedules.project_id')
->leftjoin('project_schedule_details', 'project_schedules.id', '=', 'project_schedule_details.schedule_id')
->leftjoin('project_schedule_visits', 'projects.id', '=', 'project_schedule_visits.project_id')
// issue tables (project_admins) and (project_shoppers)
->leftjoin('project_admins', 'projects.id', '=', 'project_admins.project_id')
->leftjoin('project_shoppers', 'projects.id', '=', 'project_shoppers.project_id')
->groupBy('projects.id')
->select(
'projects.name as project',
'customers.companyName as customer',
'project_schedule_details.date as schedule_date',
'project_schedule_details.description as schedule_description',
'project_schedule_details.actual_cost as schedule_actual_cost',
'project_schedule_visits.from_date as visit_from_date',
'project_schedule_visits.to_date as visit_to_date',
'project_schedule_visits.description as visit_description'
// 'project_admins.user.username as admin' //i.e. user 1
// 'project_shoppers.user.username as shopper' // i.e user 2
)
->get();
Explanation:
I need to join users table to project_admins table as well as project_shoppers table and return related users to those tables.
Then I would have user 1 returned based on project_admins table
And user 2 based on project_shoppers table.
Any idea how to achieve that goal?
Under the leftJoins you can add the extra joins for getting the users:
->leftJoin('users','users2.id','=','project_admins.user_id')
->leftJoin('users AS users2','users2.id','=','project_shoppers.user_id')
In your select you can get the details like this:
->select(
...,
'users.username AS admin',
'users2.username AS shopper'
)

Display results based on orWhere statement

I'm trying to figure out how to use the orWhere stament in laravel. I'm building a small app, allowing (gaming) clans to challenge other clans, either challenging a clan directly or challenge a match placed by another clan.
A clan can create a match or when challenging another team, a match is automatically created with a boolean that the match is a challenge. A clan that challenges another clan is always the "home playing team".
I want to display all received challenges (clan challenges or match challenges and how much), for all matches and clans a user is in. So yes, both teams and matches can have multiple challenges.
With my following code, I'm trying to get all the received challenges from my database for the current user and the $team_id_arr contains an array with all the team ids of a user.
$receivedChallenges = DB::table('challenges')
->select(
'matches.id as id',
'matches.date as date',
'matches.time as time',
'challenges.id as challenge_id',
DB::raw('count(challenges.id) as challenge_amount')
)
->leftjoin('matches', 'matches.id', '=', 'challenges.match_id')
->leftjoin('team_user as ht', 'ht.team_id', '=', 'matches.home_id')
->leftjoin('team_user as at', 'at.team_id', '=', 'matches.away_id')
->where('matches.played', '=', false)
->where('matches.planned', '=', false)
->where(function($query) use ($team_id_arr) {
$query
->where('matches.challenge', '=', true)
->where('at.user_id', '=', auth()->user()->id)
->where('challenges.opponent_id', 'matches.away_id')
// Or where...
->orWhere('matches.challenge', '=', false)
->where('challenges.opponent_id', $team_id_arr);
})
->havingRaw('count(challenges.id) > ?', [0])
->groupBy('matches.id')
->get();
When a match is a challenge, the current user is in the "away playing team", thus being the opponent_id in the challenge table.
When a match is not a challenge, the current user is always the clan filling opponent_id in the challenges table.
I'm using the havingRaw to only display the matches that have a challenge and I want to sort everything based on the matches.id. Is my use of the orWhere correct, because currently the received challenges for my dummy clan aren't showing up on my page.
In SQL (mySQL for example),
A AND B AND C OR D AND E
would be interpreted as
(A AND B AND C) OR (D AND E).
But since Eloquent allows queries to be constructed with commands in any order, some practices from SQL have to be translated differently.
In the case of orWhere, I highly recommend isolating the two alternate clauses.
$receivedChallenges = DB::table('challenges')
->select(
'matches.id as id',
'matches.date as date',
'matches.time as time',
'challenges.id as challenge_id',
DB::raw('count(challenges.id) as challenge_amount')
)
->leftjoin('matches', 'matches.id', '=', 'challenges.match_id')
->leftjoin('team_user as ht', 'ht.team_id', '=', 'matches.home_id')
->leftjoin('team_user as at', 'at.team_id', '=', 'matches.away_id')
->where('matches.played', '=', false)
->where('matches.planned', '=', false)
->where(function($query) use ($team_id_arr) {
$query->where(function($query){
$query
->where('matches.challenge', '=', true)
->where('at.user_id', '=', auth()->user()->id)
->where('challenges.opponent_id', 'matches.away_id')
})->orWhere(function($query) use($team_id_arr){
$query
->where('matches.challenge', '=', false)
->where('challenges.opponent_id', $team_id_arr);
});
})
->havingRaw('count(challenges.id) > ?', [0])
->groupBy('matches.id')
->get();

List all users and their recipes

I'm writing a custom database query in Laravel for my cocktail app. The goal is to retrieve the following structure:
User 1
Recipe 1
Recipe 4
User 2
Recipe 2
Recipe 3
etc...
My code (see below) currently returns 3 objects, all containing a single recipe but all from 2 users. Is it even possible to build the desired structure (see above), retrieving a user and having his/her recipes stored in a array/object called recipes?
$recipes = DB::table('users')
->join('recipes', 'users.id', '=', 'recipes.user_id')
->select(
'recipes.id as recipe_id',
'recipes.name as recipe_name',
'recipes.short as short',
'users.name as user_name'
)
->get();
While in Laravel, use Eloquent.
In your User model add relationship to recipes:
public function recipes()
{
return $this->hasMany('App\Recipe');
}
To call it:
$recepies = App\User::find(1)->recipes;
https://laravel.com/docs/5.6/eloquent-relationships
You cannot get this format using query.
First fetch users then fetch recipes.
Then format them using loop.
OR
Use eloquent :)
$recepies = App\User::with('recipes')->get();
I think this would work
$recipes = DB::table('users')
->select(
'recipes.id as recipe_id',
'recipes.name as recipe_name',
'recipes.short as short',
'users.name as user_name'
)
->where('recipes.user_id', '=', 'users.id')
->get();

Laravel - Select only specified columns in joined tables

Here's my situation I have joined tables but the problem is some of those columns have the same name from other tables. What I want to know is how I can prevent this from happening. The columns that have the same name are created_at but I only want to use methods' table created_at (methods.created_at). Here is my code to explain my situation better
$filtered_table = Method::leftJoin('users', 'users.id', '=', 'methods.created_by')
->leftJoin('roles', 'roles.id', '=', 'users.role_id')
->leftJoin('types', 'types.id', '=', 'methods.type_id')
->where($request->filters)//will act as a searchmap
->get([ 'users.username', 'users.id AS users_id', 'methods.*', 'methods.id AS method_id', 'methods.name AS method_name', 'roles.id AS role_id', 'roles.name AS role_name',
'types.id AS type_id_typetable', 'types.name AS type_name']);
notice how ->where is an array of objects, I am using it as a searchmap for the clause. But my problem is like what I said above that the tables has the same name on some columns like for example created_at, the other columns doesn't matter since I am not using it.
The question is how do I explicitly tell the query that I am using the methods.created_at when I am searching it through the searchmap (In this case, $request->filters['created_at']. Please, let me know if you need any more details.
EDIT
if($("#date_select_off").val() == "daily") {
let day = $("#day_date").val();
filter_list.created_at = day;
}
in this code in jquery I am naming the key the same as the column so that I can use it as parameter in the php query. But my like my initial problem I simply can't name it filter_list.methods.created_at any help with this is greatly appreciated.
EDIT 2
How would I use a 'LIKE' query to that particular key value pair?
->where($request->filters)//will act as a searchmap
->orWhere('methods.created_at', 'LIKE', $request->filters['methods.created_at'])
I tried doing this but it is just wrong since the key value pair is already hitting on the first where clause.
EDIT 3
It could use some improvements but yeah
$filtered_table = Method::leftJoin('users', 'users.id', '=', 'methods.created_by')
->leftJoin('roles', 'roles.id', '=', 'users.role_id')
->leftJoin('types', 'types.id', '=', 'methods.type_id')
->where($request->filters)//will act as a searchmap
->orWhere('methods.created_at', 'LIKE', '%' . $request->filters['methods.created_at'] . '%')
->get([ 'users.username', 'users.id AS users_id', 'methods.id AS method_id', 'methods.name AS method_name', 'methods.created_at AS method_created_at', 'roles.id AS role_id', 'roles.name AS role_name',
'types.id AS type_id_typetable', 'types.name AS type_name']);
Change your model class as per your requirements to specify what columns you want selected:
public function someModel() {
return $this->belongs_to('otherModel')->select(array('id', 'name'));
}
In this case pass the fully qualified column name in where clause like:
->where('methods.created_at', '=', $request->filters)
or create a table alias and use the alias like:
SELECT col from methods as t1,
...
WHERE t1.col = 'some value';

Categories