create sub Array on join instead of new entries - php

I have 4 lectures where each lecture has it's own name:
jbc2014_lezingen
Then for each lecture there will be questions, in this case 2 for each lecture:
jbc2014_vragen
I use this query:
$query = "SELECT * FROM jbc2014_lezingen
INNER JOIN jbc2014_vragen
ON jbc2014_lezingen.id=jbc2014_vragen.lezing_id";
This results in something like:
[0] => Array
(
[id] => 1
[lezing_naam] => lezing 1
[lezing_id] => 1
[vraag] => foobar?
)
[1] => Array
(
[id] => 2
[lezing_naam] => lezing 1
[lezing_id] => 1
[vraag] => foobar?
)
etc.
So the array size is based on the amount of the questions, not the amount of the lectures.
I would like something like:
[0] => Array
(
[id] => 1
[lezing_naam] => lezing 1
[lezing_id] => 1
[questions] Array (
[0] => [vraag] => foobar?
[1] => [vraag] => foobar?
)
)
Where the questions are in an array (vraag means question).
How can this be done?
Later on I need the multiple choice answers in an array inside the questions as well. But I think that won't be hard after having this one fixed.

The closest thing you could do is something like this -
SELECT jbc2014_lezingen.id as lezing_id,
GROUP_CONCAT(vraag) as vraags
FROM jbc2014_lezingen
INNER JOIN jbc2014_vragen
ON jbc2014_lezingen.id=jbc2014_vragen.lezing_i
GROUP BY jbc2014_lezingen.id
and then just get the values with
explode(",",$row['vraags']);
or create another array with something like this
foreach($raw_result as $key => $value){
$new_array[$key]['lezing_id'] = $value['lezing_id'];
$new_array[$key]['vraags'] = explode(",",$value['vraags']);
}

Related

Codeigniter:query results into associative array

I have two tables in database
1.main_category fields (id,main_name);
2.sub_category fields(id,main_id, sub_name)
Here main_id is used for connecting two tables from this i want to get the result like the following array
Array
(
[CCTV] => Array
(
[0] => Array
(
[id] => 1
[main_id] => 4
[name] => first
)
[1] => Array
(
[id] => 3
[main_id] => 4
[name] => second
)
[2] => Array
(
[id] => 4
[main_id] => 4
[name] => second
)
)
[Security Camera] => Array
(
[0] => Array
(
[id] => 5
[main_id] => 5
[name] => first
)
[1] => Array
(
[id] => 6
[main_id] => 5
[name] => second
)
[2] => Array
(
[id] => 7
[main_id] => 5
[name] => second
)
)
)
Here the key of the array are main_name field which is from the main_category table and the associative array for each key contains the rows which matches the condition
where main_category.id=sub_category.main_id
I want db query to achieve the above result.is it possible with a join query?
This is the structure of the join query you can change it in your own requirement.
function myfun($id){
$query = "select main_cat.*, sub_cat.* from main_category main_cat
Join sub_category sub_cat
ON main_cat.id = sub_cat.main_id
where main_cat.id = $id";
$data = $this->db->query($query);
return $data->result_array();
}
Hope this will help to you.
try to understand the query and make alteration as required.main_cat as table 1 and sub_category as table two . already you have gave half solution sub_category.employee_id = main_cat.employee_id
$this->db->select("main_cat.id,main_cat.main_id,main_cat.name,sub_category.id,sub_category.main_id,sub_category.sub_name");
$this->db->from('main_cat');
$this->db->join('sub_category', 'sub_category.employee_id = main_cat.employee_id');
$this->db->where('id', $id);
$query = $this->db->get();
return $query->result();
Hello You use codeignitor so use codeignitor mysql query structure it's best practise in future
$this->db->select("main_cat.id,main_cat.main_id,main_cat.name,sub_category.id,sub_category.main_id,sub_category.sub_name");
$this->db->from('main_cat');
$this->db->join_using('sub_category', 'employee_id');
$this->db->where(tablename.'id', $id);
$query = $this->db->get();
return $query->result();
employee_id is common in both table so use join_using other wise you use join like this
$this->db->join('sub_category', 'sub_category.employee_id = main_cat.employee_id');

Custom array Index in Mysql Alias

I wanted to know if it is possible to list the records of a Mysql query into custom arrays
Like when I do
SELECT CAT.catgryname,count(JB.knifeid) AS total
FROM jbs AS JB
LEFT JOIN krgstrs AS KR ON KR.id = JB.knfid
LEFT JOIN accnts AS ACC ON ACC.job_id = JB.id
LEFT JOIN catgor AS CAT ON CAT.id = KR.subctid
WHERE JB.usrid =xxx
GROUP BY CAT.catgryname
it gives me
[0] => Array
(
[CAT] => Array
(
[categoryname] => Fridge Magnet
)
[0] => Array
(
[total] => 22
[MNTH] => Jan
)
)
I wanted to have a custom index instead of a 0 for the second array nested inside like
[0] => Array
(
[CAT] => Array
(
[categoryname] => Fridge Magnet
)
[DET] => Array
(
[total] => 22
[MNTH] => Jan
)
)
Note the DET instead of a 0 here.
I tried
SELECT CAT.catname,count(cat.id) as DET.total
But it throws an error as I think it interprets DET to be a table here.
Thanks All.
I wouldn't do this on DB-Side.
However i don't know how you get the array (using mysqli or mysql PHP extension). Regardless of that, just do that on the PHP-Side, as pointed out in the comments.
Try using this ($results is the array you have as described - with indexes CAT and 0)
$newArray = array();
foreach($results as $result) {
$newArray[] = array(
'CAT' => array(
'categoryname' => $result["CAT"]["categoryname"]
),
'DET' => array(
'total' => $result[0]["total"],
'MNTH' => $result[0]["MNTH"]
)
);
}
And there you go with $newArray

trying to get a multi table sql query into one result array

I have four tables: followers, users, mixes, songs I am trying to get all the mixes from all the followers of one user, I have that part figured out, but I also want to get the songs from each of those mixes, currently my query is giving me results but each result is for one song on the mix, rather than an array of songs within each result for one mix ... any help would be amazing, my sql skills aren't the greatest and I have spent a lot of time trying to figure this out!
my current query is:
SELECT followers.following_id, users.id, users.user_username, mixes.id, mixes.mix_created_date, mixes.mix_name,songs.song_artist
FROM followers, users, mixes,songs
WHERE followers.user_id = 46
AND users.id = followers.following_id
AND mixes.user_id = followers.following_id
AND mixes.id > 0
ORDER BY mixes.mix_created_date DESC
LIMIT 10
the current result is (from running this through a cakephp custom query)
Array
(
[0] => Array
(
[followers] => Array
(
[following_id] => 47
)
[users] => Array
(
[id] => 47
[user_username] => someguy
)
[mixes] => Array
(
[id] => 45
[mix_created_date] => 2012-07-21 2:42:17
[mix_name] => this is a test
)
[songs] => Array
(
[song_artist] => Yo La Tengo
)
)
[1] => Array
(
[followers] => Array
(
[following_id] => 47
)
[users] => Array
(
[id] => 47
[user_username] => someguy
)
[mixes] => Array
(
[id] => 45
[mix_created_date] => 2012-07-21 2:42:17
[mix_name] => this is a test
)
[songs] => Array
(
[song_artist] => Animal Collective
)
)
as you can see the mix id's are the same, I am trying to get the songs to be an array inside of each result like :
Array
(
[0] => Array
(
[followers] => Array
(
[following_id] => 47
)
[users] => Array
(
[id] => 47
[user_username] => someguy
)
[mixes] => Array
(
[id] => 45
[mix_created_date] => 2012-07-21 2:42:17
[mix_name] => this is a test
)
[songs] => Array
(
[0]=>array(
['song_artist'] => Yo La Tengo
),
[1]=>array(
['song_artist'] => Animal Collective
)
)
)
Really hoping this can be done with just one sql statement! thanks in advance!
You can use the SQL join command to make multiple queries together..
Use this...
sql_join
first a note: it looks like you have a missing condition. according to the above query, every song in songs table will be joined with every result possible. probably there should be a condition similar to the following added: (column names can be different based on your tables):
...
and mix.song_id=songs.song_id
...
as for your question: I don't know php so i regard mysql alone: I don't think it is possible to do it with mysql. mysql returns rows in the result set and each row can contain a single value in each column. to add a group of values (song names) in one column, they must be concatenated (and that is possible: Can I concatenate multiple MySQL rows into one field?), and later you split them back in your php script. this is not a good idea as you will need to choose a separator that you know will never appear in the values that are concatenated. therefore I think its better to remove the songs table from the query and after getting the mix id, run a second query to get all songs in that mix.

cakephp - sorting by a second level association in paginate

I am playing around with a quotes database relating to a ski trip I run. I am trying to list the quotes, but sort by the person who said the quote, and am struggling to get the paginate helper to let me do this.
I have four relevant tables.
quotes, trips, people and attendances. Attendances is essentially a join table for people and trips.
Relationships are as follows;
Attendance belongsTo Person hasMany Attendance
Attendance belongsTo Trip hasMany Attendance
Attendance hasMany Quote belongs to Attendance
In the QuotesController I use containable to retrieve the fields from Quote, along with the associated Attendance, and the fields from the Trip and Person associated with that Attendance.
function index() {
$this->Quote->recursive = 0;
$this->paginate['Quote'] = array(
'contain' => array('Attendance.Person', 'Attendance.Trip'));
$this->set('quotes', $this->paginate());
}
This seems to work fine, and in the view, I can echo out
foreach ($quotes as $quote) {
echo $quote['Attendance']['Person']['first_name'];
}
without any problem.
What I cannot get to work is accessing/using the same variable as a sort field in paginate
echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');
or
echo $this->Paginator->sort('Location', 'Attendance.Trip.location');
Does not work. It appears to sort by something, but I'm not sure what.
The $quotes array I am passing looks like this;
Array
(
[0] => Array
(
[Quote] => Array
(
[id] => 1
[attendance_id] => 15
[quote_text] => Hello
)
[Attendance] => Array
(
[id] => 15
[person_id] => 2
[trip_id] => 7
[Person] => Array
(
[id] => 2
[first_name] => John
[last_name] => Smith
)
[Trip] => Array
(
[id] => 7
[location] => La Plagne
[year] => 2000
[modified] =>
)
)
)
I would be immensely grateful if someone could suggest how I might be able to sort by the the first_name of the Person associated with the Quote. I suspect my syntax is wrong, but I have not been able to find the answer. Is it not possible to sort by a second level association in this way?
I am pretty much brand new with cakephp so please be gentle.
Thanks very much in advance.
I've had the similar problem awhile back. Not with sort though. Try putting the associated table in another array.
echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');
change to:
echo $this->Paginator->sort('Name', array('Attendance' => 'Person.first_name'));
Hope this helps
i'm also looking for help with this.
so far i've found that you can sort multi level associations in controller's pagination options after using the linkable plugin https://github.com/Terr/linkable.
but it breaks down when you try to sort form the paginator in the view. i'm using a controller for magazine clippings. each clipping belongs to an issue and each issue belongs to a publication.
$this->paginate = array(
"recursive"=>0,
"link"=>array("Issue"=>array("Publication")),
"order"=>array("Publication.name"=>"ASC",
"limit"=>10);
after debugging $this->Paginator->params->paging->Clipping in the view, you can see that the sort is described in two separate places, "defaults" and "options". the sort info needs to be present in both for it to work in the view.
here is after setting order in controller:
[Clipping] => Array
(
[page] => 1
[current] => 10
[count] => 6685
[prevPage] =>
[nextPage] => 1
[pageCount] => 669
[defaults] => Array
(
[limit] => 10
[step] => 1
[recursive] => 0
[link] => Array
(
[Issue] => Array
(
[0] => Publication
)
)
[order] => Array
(
[Publication.name] => ASC
)
[conditions] => Array
(
)
)
[options] => Array
(
[page] => 1
[limit] => 10
[recursive] => 0
[link] => Array
(
[Issue] => Array
(
[0] => Publication
)
)
[order] => Array
(
[Publication.name] => ASC
)
[conditions] => Array
(
)
)
)
and here is after using $this->Paginator->sort("Publication","Publication.name");.
notice the options array is empty.
[Clipping] => Array
(
[page] => 1
[current] => 10
[count] => 6685
[prevPage] =>
[nextPage] => 1
[pageCount] => 669
[defaults] => Array
(
[limit] => 10
[step] => 1
[recursive] => 0
[link] => Array
(
[Issue] => Array
(
[0] => Publication
)
)
[order] => Array
(
[Publication.name] => DESC
)
[conditions] => Array
(
)
)
[options] => Array
(
[page] => 1
[limit] => 10
[recursive] => 0
[link] => Array
(
[Issue] => Array
(
[0] => Publication
)
)
[order] => Array
(
)
[conditions] => Array
(
)
)
does one really need to modify the paginator class to make this work?
UPDATE:
i found out the problem:
in the core cake controller paginator merges default and options to create the find query.
but the options array is empty when using linkable to sort. because options is listed after default it overrides default and the empty array replaces the default array of options.
solution to this is extending the paginate function inside of app_controller.php and unsetting the options array order value if it is empty:
(line 1172 in cake/libs/controller/controller.php)
if(empty($options["order"])){
unset($options["order"]);
}
then the options will not be overwritten by thte blank array.
of course this should not be changed inside of controller.php, but put it in app_controller.php and move it to your app folder.
On CakePHP 3 this problem can be solved by adding 'sortWhitelist' params to $this->paginate on your controller.
$this->paginate = [
// ...
'sortWhitelist' => ['id', 'status', 'Attendance.Person.first_name']
];
And then in your view:
echo $this->Paginator->sort('Name', 'Attendance.Person.first_name');
This is noted in the docs:
This option is required when you want to sort on any associated data, or computed fields that may be part of your pagination query:
However that could be easily missed by tired eyes, so hope this helps someone out there!

PHP search array and add content on position where id's are equal

I have 2 assoc. Arrays which have the same structure, but only one ID is identical. I need to add content to the MainArray from the IncludeArray everytime the specific ID is identical.
Here are a sample of the Arrays (MainArray could hold up to 100 or more items, the sample contains only a portion of the real content):
$MainArray = Array
(
[0] => Array
(
[item_id] => 1
[name] => Test1
[helptxt] => Helptext for item-id 1.
[type_id] => 1 #could be the same for many other items!!
)
[1] => Array
(
[item_id] => 2
[name] => Test2
[helptxt] => Helptext for item-id 2.
[type_id] => 2 #could be the same for many other items!!
)
and a lot more Arrays
)
$IncludeArray = Array
(
[0] => Array
(
[type_id] => 1
[typetitle] => Number
[typedesc] => Description Text type_id 1
)
[1] => Array
(
[type_id] => 2
[typetitle] => Value
[typedesc] => Description Text type_id 2
)
)
The desired new array should be:
$NewMainArray = Array
(
[0] => Array
(
[item_id] => 1
[name] => Test
[helptxt] => Helptext for item-id 1.
[type_id] => 1
[typetitle] => Number
[typedesc] => Description Text type_id 1
)
[1] => Array
(
[item_id] => 2
[name] => Test2
[helptxt] => Helptext for item-id 2.
[type_id] => 2
[typetitle] => Value
[typedesc] => Description Text type_id 2
)
And so on with all other items in the Array.
)
So eachtime a type_id is found in $MainArray the content of [typetitle] + [typedesc] should be added to the $NewMainArray.
Most of my tests ended in having the Arrays only merged or just added the $IncludeArray only once. Even my Forum Searches don't got me to a solution.
The Arrays are created from 2 separate DB-Requests, which I couldn't join (Already tried several attempts). This is related to different WHERE and AND clauses, which don't work on a joined request.
I hope there is a smart way to get the desired $NewMainArray. BTW I use PHP4 and I'm a newbie to PHP (at least for this kind of problem).
Thanks a lot for your help.
Try this:
/**
* Simulates relational table behaviour by joining data matching an ID value.
* Works with single-nested arrays.
*
* #author Joel A. Villarreal Bertoldi
*
* #param $source array The source array.
* #param $include_to_row array The row where we'll deposit the joined data.
* #param $match string Unique id field name.
*
* #return array Row with joined data.
*/
function includeFromArray($source, $include_to_row, $match)
{
foreach ($source as $source_row)
{
if ($source_row[$match] == $include_to_row[$match])
{
foreach ($source_row as $source_column_key => $source_column_value)
{
$include_to_row[$source_column_key] = $source_column_value;
}
}
}
return $include_to_row;
}
for ($ma = 0; $ma < count($MainArray); $ma++)
$NewMainArray[$ma] = includeFromArray($IncludeArray, $MainArray[$ma], "type_id");
Results:
Array
(
[0] => Array
(
[item_id] => 1
[name] => Test1
[helptxt] => Helptext for item-id 1.
[type_id] => 1
[typetitle] => Number
[typedesc] => Description Text type_id 1
)
[1] => Array
(
[item_id] => 2
[name] => Test2
[helptxt] => Helptext for item-id 2.
[type_id] => 2
[typetitle] => Value
[typedesc] => Description Text type_id 2
)
)
Take a look at the array_merge_recursive function ;)
http://nl2.php.net/manual/en/function.array-merge-recursive.php

Categories