get array output as key value on doctrine querybuilder - php

I have two tables for example
student
id name
1 John
2 Doe
subject
id sub student
1 eng 1
2 maths 1
I have a query as follows on student repository
$this->createQueryBuilder('stud')
->select('stud.name,s.sub')
->leftJoin('AppBundle:subject', 's', 'WITH', 's.student = stud.id')
->getQuery()
->getArrayResult();
But I am getting 3 rows with 2 rows as john with different sub and one row as doe.
How could I make it two rows with the sub as an array on the result? I am new to query writing. Hope someone could help
Getting output
array:3 [▼
0 => array:2 [▼
"name" => John
"sub" => maths
]
1 => array:2 [▼
"name" => John
"sub" => eng
]
2 => array:2 [▼
"name" => Doe
"sub" => null
]
]
Expecting output
array:2 [▼
0 => array:2 [▼
"name" => John
"sub" => array:2['eng','maths']
]
2 => array:2 [▼
"name" => Doe
"sub" => null
]
]

The LEFT JOIN returns all records from the left table (here: student), and the matched records from the right table (here: subject). The result is NULL from the right side if there is no match(here: student with id:2).
Here, you should select from subject, then LEFT JOIN it with students. it solves your problem.

Related

getting emptied while checking if an array value exists - laravel?

I wanted to insert the id values of $courseCat if that id is not present in $m.In the below code, i feel the $m array is getting emptied every time and so, all id's are getting inserted to the $m ,as the result of dump($m) indicates.How can i fix this?
$m=[];
$courseCat = MyCourse::where('course_id', $key['courseId'])->get()->toArray();
foreach($courseCat as $k=>$c){
// dump($courseCat);
if(!in_array($c['id'],$m)){
array_push($m,$c['id']);
}
}
//dump($m);
dump($courseCat); shows the following result
array:2 [
0 => array:19 [
"id" => 2
"course_id" => 18
]
1 => array:19 [
"id" => 3
"course_id" => 18
]
]
array:2 [
0 => array:19 [
"id" => 2
"course_id" => 18
]
1 => array:19 [
"id" => 3
"course_id" => 18
]
]
array:2 [
0 => array:19 [
"id" => 5
"course_id" => 1
]
1 => array:19 [
"id" => 6
"course_id" => 1
]
]
array:2 [
0 => array:19 [
"id" => 5
"course_id" => 1
]
1 => array:19 [
"id" => 6
"course_id" => 1
]
]
dump($m) shows the below result:
array:2 [
0 => 2
1 => 3
]
array:2 [
0 => 2
1 => 3
]
array:2 [
0 => 6
1 => 5
]
array:2 [
0 => 6
1 => 5
]
Below attached images are the result of the query MyCourse::where('course_id', $key['courseId'])->get().
[enter image description here]1
[enter image description here]2
[enter image description here]3
Expected result :
dump($m) should show the below result
[0=>2,
1=>3,
2=>5,
3=>6]
I think it's because you have an outer loop not shown in the question. You need to declare $m before the outer loop:
$m=[];
foreach($keys as $key){
$courseCat = MyCourse::where('course_id', $key['courseId'])->get()->toArray();
foreach($courseCat as $k=>$c){
if(!in_array($c['id'],$m)){
array_push($m,$c['id']);
}
}
}
dump($m);
If you want all the values of a column from your query you can use pluck:
MyCourse::where('course_id', $key['courseId'])->pluck('id')
Now you have a list of all the 'id's.
Laravel 8.x Docs - Database - Running Database Queries - Retrieving a List of Column Values pluck

add associative arrays with different keys to main associative array

Have problem with associative array.
I have code:
$array[]=[$key=>['value'=>$value,'value1'=>$value1'];
$key value can be repeated, it means that for $key = 4 we can have few options of $value and $value1.
It generates structure as following:
[0]=>[4=>['value'=>$value,'value1'=>$value1'];
[1]=>[4=>['value'=>$value,'value1'=>$value1'];
[2]=>[4=>['value'=>$value,'value1'=>$value1'];
The think is that i want to achieve different structure:
[4]=>[0=>['value'=>$value,'value1'=>$value1'];
[1 =>['value'=>$value,'value1'=>$value1'];
[2 =>['value'=>$value,'value1'=>$value1'];
laravel dd should show it that way:
^ array:1 [▼
4 => array:1 [▼
0 => array:2 [▶]
1 => array:2 [▶]
2 => array:2 [▶]
]
]
Inside array with key 4 i want to put few arrays with keys as following 0,1,2 etc.
I tried like so:
$array[$key]=[['value'=>$value,'value1'=>$value1']];
but its overriding inside array key, and any time its = 0 like here:
[4]=>[0=>['value'=>$value,'value1'=>$value1'];
laravel:
array:1 [▼
4 => array:1 [▼
0 => array:2 [▶]
]
]
What a shame just after post I get an idea.
$array[$key][]=['value'=>$value,'value1'=>$value1'];
That what I was looking for.

How to properly get the info from the arrays so is possible to insert in database?

After a user fill a form to register two participants in the conference and click in "Register", there is an array with the request data.
The request data has the array name that stores the name of the participant being registered in the registration_type_id "1" (Jake) and the name of the participant being registered in the registration_type_id "4" (John).
The same for the surname array, this surname array stores each surname for each registration type.
And the same for the answer array that stores each answer for each registration type.
"name" => array:2 [▼
1 => array:1 [▼
1 => "Jake"
]
4 => array:1 [▼
1 => "John"
]
]
"surname" => array:2 [▼
1 => array:1 [▼
1 => "W"
]
4 => array:1 [▼
1 => "K"
]
]
"answer" => array:1 [▼
1 => array:1 [▼
1 => array:6 [▼
1 => "answer1"
2 => "answer2"
]
]
]
Doubt: My doubt is how to get the info from this array structure above in order to store each participant in the participants table and also how to store each answer in the answers table.
With the array content above the participants table should stay like:
id registration_type_id name surname registration_id
1 1 Jake W 1
2 4 John K 1
The answers table should stay like:
id participant_id question_id answer
1 1 1 answer1
1 1 2 answer2
Do you know how to properly achieve that?
I have the code below that first insert an entry in the registrations table to store the registration:
# user object
$user = Auth::user();
# add registration to Database
$registration = Registration::create([
'conference_id' => $id,
'user_that_did_registration' => $user->id]
);
But then is necessary to store each participant in the articipants table and also each answer in the answers table. Do you know how to properly get the necessary info from the above array to store in the participants table and in the answers table with the code below?
To insert in the participants table it is necessary to use:
$participant_result = Participant::create([
'name' => how to get the name of each participant from the array?,
'surname' => how to get the surname of each participant from the array?,
'registration_id' => $registration->id,
'registration_type_id' => how to get the registration_type_id from the array?
]);
To insert in the answers table it is necessary to use:
$answer = Answer::create([
'question_id' => how to get each question id from the array?,
'participant_id' => $participant_result->id,
'answer' => how to get each answer from the array?
]);

array values with where condition in laravel query

I have an array called assetIDs as below
$assetIDs = Collection {#505 ▼
#items: array:2 [▼
0 => 4
1 => 7
]
}
and I have the data in the table as below shown
and I'm doing query on the above table using this
$supplier_id = SupplierAsset::whereIn('asset_id',$asset_ids)->pluck('supplier_id');
and result for the above query is below
Collection {#510 ▼
#items: array:3 [▼
0 => 1
1 => 1
2 => 2
]
}
here whereIn is returning all the possible rows which satisfies the condition. Actually I need to get the result as like which supplier_id has both the values of assetIDs array.In my table supplier_id=1 has the both values 4 and 7 Just like below collection.
Collection {#510 ▼
#items: array:3 [▼
0 => 1
1 => 1
]
}
Can anybody suggest me the solution for this please?
You can try:
$supplier_id = SupplierAsset::whereIn('asset_id',$asset_ids)
->groupBy('supplier_id')
->havingRaw('count(distinct asset_id) = ' . count($assetIDs))
->pluck('supplier_id');
Here is the mysql you should do :
1- get all the id who have more than 1 supplier_id :
SELECT supplier_id, Count(distinct asset_id) as dist_asst
FROM Table
GROUP BY supplier_id
HAVING dist_asst > 1
2- then doing a join :
SELECT t1.supplier_id
FROM Table t1
INNER JOIN (SELECT supplier_id, Count(distinct asset_id) as dist_asst
FROM Table
GROUP BY supplier_id
HAVING dist_asst > 1) t2 on t2.supplier_id = t1.supplier_id

Php sorting based on ID and ParentID

i have the following array structure:
| ID | CategoryName | ParentID
_________________________________
1 | Movies | -1
_________________________________
2 | Series | -1
_________________________________
3 | ActionMovies | 1
_________________________________
4 | HorrorMovies | 1
_________________________________
5 | ComedySeries | 2
_________________________________
6 | TVShows | -1
My goal is to reach the following structure
Goal:
| ID | CategoryName | ParentID
_________________________________
1 | Movies | -1
_________________________________
3 | ActionMovies | 1
_________________________________
4 | HorrorMovies | 1
_________________________________
2 | Series | -1
_________________________________
5 | ComedySeries | 2
_________________________________
6 | TVShows | -1
Or explained in word:
Parent-Categories have ParentID = -1 (Example Movies)
All categories keep their original ID-Number
Should come listed directly after their ParentCategory (Example ActionMovies)
RootCategories without Children, come listed at the end of array. (Example TVShows)
How can i achieve this best with PHP? I have no access to the original Mysql query, so that is not an option :)
i have started with this code, but i am not sure it is the right path, and with minimal efforts/readability
$tmpList = Categories_Models_Main::getAllCategories();
$categoryData = array();
foreach ($tmpList as $index => $categoryObject) {
$categoryData[] = array('id' => $categoryObject->id,
'CategoryName' => $categoryObject->parentId,
'name' => $categoryObject->name);
}
///let us assume $categoryData is original state.
///Beginning of manipulation and re-sorting of $tmpList
foreach ($categoryData as $key => $value) {
$mainId[$key] = $value['id'];
$parentId[$key] = $value['parentId'];
}
array_multisort($parentId, $mainId, $categoryData);
Split the main array into two, one with those nodes that doesn't have childs and other with rests of items.
Do the sorting into array of items with array_multisort function and do too a sorting into array of categories without childs using the criteria that you want. The final step will be push the array without childs to the other.
This form isn't the most efficient, but to have a first approach is valid, after this, you can dispense time optimizing the code.
$input = array(
array("foo", "bar", "5"),
array("barr", "baz", "9"),
array("nyan", "nyu", "2")
);
usort($input, function($a, $b) {
if($a[2] < $b[2]) {
return -1;
} else if($a[2] > $b[2]) {
return 1;
} else {
return 0;
}
});
var_dump($input);
Do you mean something like this? The idea is to manually compare the contents of the array using condition you know. Since the thing what is to be sorted is unique, the logic how to sort must be always implemented. With PHP, PHP’s sorting functions most of time does it correctly.
I am pretty sure that this does not answer your question, but might give you some ideas how to make your life easier. This is javascript approach of the problem, but this way you won't even have to think about sorting anything. You just provide parents and children and it is sorted for you and ready to use. A pretty nice way in my opinion. Yet it is probably irrelevant to what you are trying to do, but maybe for some other similar problem you would see this as a solution: https://developers.google.com/chart/interactive/docs/gallery/orgchart
The only way to solve this problem is by using a bottom up approach (i am referring to the pyramids).
Explanation
We need to start with rows (entries) within an array that do not have parents. In my case, it's any element that has "parent_id = 0". Once we have those, we need to build children elements for each parent element.
The latter part would be done recursively by calling sorting method until the element which we are processing has not children. The results from the sorting method are passed down to the previous array point until the array is complete.
Code
Class Categories {
private $cats;
public function getAllCategoriesSorted() {
/**
* $this->cats = [
* 'id' => x, 'parent_id' => x
* ];
*/
$this->cats = Category::get()->toArray();
# find categories with no parents
$keys = array_keys(array_column($this->cats, 'parent_id'), 0);
$return = [];
# loop through each and populate each one
foreach ($keys as $key) {
$return[$this->cats[$key]['id']] = $this->sortCategories($this->cats[$key]);
}
dd($return);
}
private function sortCategories($currentElement) {
# we need to check if current element has any children
$keys = array_keys(array_column($this->cats, 'parent_id'), $currentElement['id']);
if ($keys === false || empty($keys)) {
# we are dealing with childless element, we should return it as it is
return $currentElement;
}
# we are dealing with element that has children, we need to loop through each child
$currentElement['children'] = [];
foreach ($keys as $key) {
$currentElement['children'][$this->cats[$key]['id']] = $this->sortCategories($this->cats[$key]);
}
return $currentElement;
}
}
Example result
array:2 [▼
65 => array:4 [▼
"id" => 65
"name" => "Parent 1"
"parent_id" => 0
"children" => array:14 [▼
66 => array:4 [▼
"id" => 66
"name" => "Child 1"
"parent_id" => 65
"children" => array:22 [▶]
]
87 => array:4 [▼
"id" => 87
"name" => "Child 2"
"parent_id" => 65
"children" => array:31 [▶]
]
117 => array:4 [▶]
118 => array:4 [▶]
120 => array:4 [▶]
124 => array:4 [▶]
125 => array:4 [▶]
127 => array:4 [▶]
225 => array:4 [▶]
305 => array:4 [▶]
434 => array:4 [▶]
321 => array:4 [▶]
348 => array:4 [▶]
468 => array:4 [▶]
]
]
64 => array:4 [▼
"id" => 64
"name" => "Parent 2"
"parent_id" => 0
"children" => array:5 [▼
128 => array:4 [▶]
132 => array:4 [▼
"id" => 132
"name" => "Child 3"
"parent_id" => 64
"children" => array:22 [▼
202 => array:3 [▶]
203 => array:3 [▼
"id" => 203
"name" => "Child 4"
"parent_id" => 132
]
204 => array:3 [▶]
205 => array:3 [▶]
206 => array:3 [▶]
207 => array:3 [▶]
208 => array:3 [▶]
209 => array:3 [▶]
210 => array:3 [▶]
211 => array:3 [▶]
212 => array:3 [▶]
213 => array:3 [▶]
214 => array:3 [▶]
215 => array:3 [▶]
216 => array:3 [▶]
217 => array:3 [▶]
218 => array:3 [▶]
220 => array:3 [▶]
221 => array:3 [▶]
222 => array:3 [▶]
223 => array:3 [▶]
224 => array:3 [▶]
]
]
134 => array:4 [▶]
394 => array:4 [▶]
454 => array:4 [▶]
]
]
]

Categories