I want to get the sum of prices from contract table and sum of transactions together connected to user id. And how can i use where in this.
Table Contracts:
[
{
"id": 1,
"user_id":97,
"price":"100"
},
{
"id": 2,
"user_id":97,
"price":"200"
},
{
"id": 3,
"user_id":97,
"price":"300"
}
]
Table Transactions:
[
{
"id": 1,
"user_id":97,
"sum":"100"
},
{
"id": 2,
"user_id":97,
"sum":"200"
},
{
"id": 3,
"user_id":97,
"sum":"300"
}
]
My query:
$query = User::where([
['contracts_sum', '<', 'transactions_sum'],
])
->join('contracts', 'contracts.user_id', '=','users.id')
->join('transactions', 'users.id', '=','transactions.user_id')
->groupBy(['users.id'])
->select(
'users.id', 'users.name',
DB::raw('SUM(contracts.price) AS contracts_sum'),
DB::raw('SUM(transactions.sum) AS transactions_sum'),
)
->get();
But this variant returns sum multiplied to count of transactions table rows like this:
[
{
"id":97,
"name":"JOHN",
"contracts_sum":"1800",
"transactions_sum":"1800"
}
]
But i would like to get the data in this kind of form:
[
{
"id":97,
"name":"JOHN",
"contracts_sum":"600",
"transactions_sum":"600"
}
]
My advice would be to make use of laravel's relation feature, as it would make it a lot easier.
class User
{
public function transactions()
{
return $this->hasMany(Transaction::class, 'user_id', 'id');
}
public function contracts()
{
return $this->hasMany(Contract::class, 'user_id', 'id');
}
}
Then, in your controller, you could do the following:
$user = User::where('id', 97)
->withSum('contracts', 'price')
->withSum('transactions', 'sum')
->get();
return [
'id' => $user->id,
'name' => $user->name,
'contracts_sum' => $user->transactions_sum_sum,
'transactions_sum' => $user->contracts_sum_price
];
Not only does this look a lot cleaner, the query will be more efficient as well. More information on the aggregate functions can be found in the laravel documentation.
Related
this object:
"permission_category": [{
"id": 2,
"name": "user",
"permissions": {
"id": 2,
"name": "userCreate"
}
},
{
"id": 2,
"name": "user",
"permissions": {
"id": 3,
"name": "userUpdate"
}
}
]
can i convert it to this?
"permission_category": [{
"id": 2,
"name": "user",
"permissions": [
{
"id": 2,
"name": "userCreate"
},
{
"id": 3,
"name": "userUpdate"
},
]
}
]
Do I have such a chance? Because if I return this with foreach it will print the same category name more than once. Is it possible to show both userCreate and userUpdate permissions belonging to the user category under one category? The object looks like this to me. I have created a relationship between 4 tables in Laravel. I will share their code with you too. Please tell me if what I need to do is change the code between relationships. Please tell me if what I need to do is to edit the array in the output with php array functions. I don't know anything about this, I need some help. Sorry for prolonging the topic. I'm sure there's a right and easy way to do this. Since I don't know, I had to ask. I would like to express my thanks and regards to those who have helped in advance.
Laravel Relationship:
UsersController.php
public function add() {
$data = array();
$user = AdminUsers::where('id', $this->uid())->first();
if($user->hasAdministrator()->first())
$data['permission_category'] = PermissionCategory::with('permissions')->get();
else
$data['permission_category'] = PermissionsResource::collection($user->permissions()->with('category')->get());
return $data;
die();
return view('admin.users.add', $data);
}
PermissionsResource.php
return [
"id" => $this->category[0]->id,
"name" => $this->category[0]->name,
"permissions" => [
"id" => $this->id,
"name" => $this->name
],
];
AdminUsers.php (Model)
public function permissions() {
return $this->belongsToMany(Permissions::class, 'admin_perms');
}
Permissions.php (Model)
public function category() {
return $this->belongsToMany(PermissionCategory::class, 'permissions', 'id');
}
admin_users table:
-id
-username
permission_category table:
-id
-name
permissions table:
-id
-permission_category_id
-name
admin_perms table:
-id
-admin_users_id foreign key
-permissions_id foreign key
do
$adminPermsWithCategory = AdminPerms::with('permission.category')
->where('admin_users_id', $user->id);->get();
return new AdminPermsResource($adminPermsWithCategory);
and in AdminPermsResource:
$data = [];
foreach ($this->resource as $item) {
if(!array_key_exists($item->permission->category->name, $data)){
$data[$item->permission->category->name] = [
"category_id" => $cat->id,
"category_name" => $cat->name,
];
}
$data[$item->permission->category->name]['permissions'][$item->permission->id] = new PermissionsResource($item->permission);
}
return $data;
and in PermissionsResource:
return [
"permission_id" => $this->id,
"permission_name" => $this->name,
];
maybe this help. I am writing without trying, sorry for the answer before.
I wrote a code to filter with the relational data, but I am not getting a good result. Here is code. The parent query and with a query is working independently.
public function get(Request $request, Company $company, Survey $survey)
{
$this->authorize('update', $survey->company);
$search = $request->get('search');
$query = EsAnswer::where(['company_id' => $company->id, 'survey_id' => $survey->id])
->orderByDesc('created_at')
->with(['employee'=> function ($q) use($search) {
$q->where('first_name', 'LIKE', "%{$search}%");
$q->orwhere('last_name', 'LIKE', "%{$search}%");
$q->select('id', 'first_name', 'last_name');
}]);
if ($request->has('start_date')) {
$query->whereDate('created_at', '>=', $request->start_date);
}
if ($request->has('end_date')) {
$query->whereDate('created_at', '<=', $request->end_date);
}
$answers = $query->get()->groupBy('submission_id');
// ->paginate('100');
return $answers;
}
when I used this
{
"search":""
}
I am getting this response:
{
"id": 2,
"company_id": 1,
"employee_id": 1,
"survey_id": 2,
"es_question_id": 1,
"answer": "done",
"submission_id": "1",
"mark_as_read": 1,
"created_at": "2020-08-19 12:18:25",
"updated_at": "2020-08-26 06:55:21",
"employee": {
"id": 1,
"first_name": "Baseapp",
"last_name": "saw"
}
}
when I tried to search by employee name which is present another table, if the data is present then data should be filtered and give a response but if the employee name or search data is not present then data should not give any response. How to deal with it?
{
"search":"sure"
}
{
"id": 2,
"company_id": 1,
"employee_id": 1,
"survey_id": 2,
"es_question_id": 1,
"answer": "done",
"submission_id": "1",
"mark_as_read": 1,
"created_at": "2020-08-19 12:18:25",
"updated_at": "2020-08-26 06:55:21",
"employee": null
}
here data is null but why parent data is showing. please help and give another idea to filter with relational data.
we use whereHas to filter in related table. so use this as like
$query = EsAnswer::with('employee:id,first_name,last_name')
->where(['company_id' => $company->id, 'survey_id' => $survey->id])
->whereHas('employee', function($query) use($search) {
$query->where('first_name', 'LIKE', "%{$search}%")
->orwhere('last_name', 'LIKE', "%{$search}%");
})
->orderByDesc('created_at');
this will search in your related table and return null if not found anything. and i have added elegant way to eager load data. you should check out this too.
it is using whereHas, then With :
$query = EsAnswer::where(['company_id' => $company->id, 'survey_id' => $survey->id])
->orderByDesc('created_at')
->whereHas('employee', function ($q) use($search) {
return $q->where('first_name', 'LIKE', "%{$search}%")
->orwhere('last_name', 'LIKE', "%{$search}%");
})->with(['employee' => function ($q){
$q->select('id', 'first_name', 'last_name');
}]);
use whereHas() function
$query = EsAnswer::with('employee:id,first_name,last_name')
->where(['company_id' => $company->id, 'survey_id' => $survey->id])
->whereHas('employee', function($query) use($search) {
$query->where('first_name', 'LIKE', "%$search%")
->orwhere('last_name', 'LIKE', "%$search%");
})
->orderByDesc('created_at');
ref link https://laravel.com/docs/7.x/eloquent-relationships#querying-relationship-existence
I am getting objects response like this:
"facilities": [
[
{
"facility_id": 1,
"speciality_id": null,
"is_facility_supervisor": 0,
"priv_key": "can_add_doctor,can_view_doctor"
}
],
{
"name": "Patient",
"role_id": 7
}
]
I want name and role_id into facilities and i want expected output like this
"facilities": [
[
{
"facility_id": 1,
"speciality_id": null,
"is_facility_supervisor": 0,
"priv_key": "can_add_doctor,can_view_doctor",
"name": "Patient",
"role_id": 7
}
],
]
How i can achieve this output name and role_id is in separate object but i want in one object like i shared.
My Code:
$specialities = DB::table('user_facility')
->select('user_facility.facility_id','user_facility.speciality_id','user_facility.is_facility_supervisor','user_facility.priv_key')
->where('user_id',$currentUser->id)->get();
$roles = DB::table('roles')
->join('user_facility', 'roles.id', 'user_facility.role_id')
->where('user_facility.user_id', Auth::user()->id)
->select('roles.name','user_facility.role_id')->first();
$superadmin = $is_super_admin->is_super_admin;
$specialities = (object) $speciality_id;
$response = ['is_super_admin' => $superadmin, 'facilities' => array_merge([$specialities,$roles])];
Your help will be highly appreciated?
How about:
$specialitiesAndRoles = DB::table('roles')
->join('user_facility', 'roles.id', 'user_facility.role_id')
->where('user_facility.user_id', Auth::user()->id)
->select('user_facility.facility_id','user_facility.speciality_id','user_facility.is_facility_supervisor','user_facility.priv_key','roles.name','user_facility.role_id')
->get();
When you are anyway joining both tables. Just select everything from the joined table. Please check/add if you have any more where clauses.
I want to pull a array from outer array.
My result
I want to remove circle symbol of array
{
"Success": "1",
"Message": "Subtopic Wise Questions...",
"Subtopic Questions": [
[
{
"id": "93",
"topic_id": "36",
"name": "Cell membrane and organelle",
"created_at": "2018-08-29 23:06:34",
"updated_at": "2018-08-29 23:06:34",
"q_count": "127"
}
],
]
}
Here is my output result of array. the
My Controller code
foreach($findid as $v)
{
$count[] = DB::table('questions')
->join('subtopics', 'subtopics.id', 'questions.subtopic_id')
->select('subtopics.*', DB::raw('count(questions.id) as q_count'))
->where('subtopic_id', $v)
->get();
}
return response([
'Success' => "1",
'Message' => "Subtopic Wise Questions...",
'Subtopic Questions' => $count
]);
use first() to obtain just an object as per your image you want to remove extra array quotes so
$count[] = DB::table('questions')
->join('subtopics', 'subtopics.id', 'questions.subtopic_id')
->select('subtopics.*', DB::raw('count(questions.id) as q_count'))
->where('subtopic_id', $v)
->first();
Hope it helps you!
use whereIn method instead of where method
note only store id in array then used whereIn method
$count = DB::table('questions')
->join('subtopics', 'subtopics.id', 'questions.subtopic_id')
->select('subtopics.*', DB::raw('count(questions.id) as q_count'))
->whereIn('subtopic_id', array_wrap($findid))
->get();
note if not working as u want restult then add toArray() method in
query like this
$count->toArray();
return response([
'Success' => "1",
'Message' => "Subtopic Wise Questions...",
'Subtopic Questions' => $count
]);
Your query is expensive. Since you are looping through array of ids, you are going to run queries count(findid) number of times. You can optimize and achieve the same as,
$count = DB::table('questions')
->join('subtopics', 'subtopics.id', 'questions.subtopic_id')
->select('subtopics.*', DB::raw('count(questions.id) as q_count'))
->whereIn('subtopic_id', $findid)
->get();
return response([
'Success' => "1",
'Message' => "Subtopic Wise Questions...",
'Subtopic Questions' => $count
]);
I got a table encuesta that has a relationship encuesta_pregunta, the table encuesta_pregunta has a relationship to encuesta_respuesta, it return this
"id": 4,
//...table info...
"encuesta_preguntas": [
{
"id": 10,
"encuesta_id": 4,
"pregunta_id": 5,
//...table info....
"encuesta_respuestas": [
//this relationship can be empty
]
},
{
"id": 11,
"encuesta_id": 4,
"pregunta_id": 3,
//...table info....
"encuesta_respuestas": [
]
},
{
"id": 12,
"encuesta_id": 4,
"pregunta_id": 2,
//...table info....
"encuesta_respuestas": [
]
}
]
}
is there a way to checheck from without looping throught each encuesta_preguntas to know if encuesta_respuesta is empty?
o get the response above like this
$encuesta = Encuesta::with(['encuestaPreguntas' => function($preguntas) {
$preguntas->with(['encuestaRespuestas' => function($respuestas) {
$respuestas->where('user_id','=',auth()->id());
}]);
}])->where('fecha_inicio','<=',date('Y-m-d'))
->where('fecha_fin','>',date('Y-m-d'))
->first();
First. You can do it with Laravel accesors
public function getHasEncuestasAttribute()
{
return $this->encuesta_pregunta != [];
}
When you do $model->has_encuestas it will become true if the relationship isn't empty.
Second. Using relationship method has or doesntHave. If you want to get all the encuesta that have empty relationship you can call Encuesta::doesntHave('encuesta_pregunta') or the opposite that dont have empty relationship Encuesta::has('encuesta_pregunta').