Getting relational data into arrays - php

I have a animal table:
id | name
1 cat
2 dog
I have a breeds table:
id | breed | color
1 siamese white
2 tabby mixed
3 golden retriever yellow
I have a animal to breeds table:
id | animal_id | breed_id
1 1 1
2 1 2
3 2 3
I want to get out each animal and all of its breeds/colors into an array which I'll then pass to JS.
So the data should look like:
array('animal' => 'cat', 'details' => array(array('breed' => 'siamese', 'color' => 'white'), array('breed' => 'tabby', 'color' => 'mixed')) 'animal' => 'dog...etc);
I'm not sure on the query though? I need to get data for all animals.

This should do the trick:
$query = "SELECT a.name, b.breed, b.colour
FROM animals a
LEFT JOIN animaltobreeds ab on a.id = ab.animal_id
LEFT JOIN breeds b on b.id = ab.breed_id";
$results = $mysqli->query($query);
$data = array(); // We'll build our results into here.
if($results->num_rows) {
while($row = $results->fetch_assoc()) {
if( ! isset($data[$row['name']]) $data[$row['name']] = array();
$data[$row['name']][] = array(
'breed' => $row['breed'],
'colour' => $row['colour']
);
}
}
Then if you want to output it for Javascript you can turn it into JSON by using json_encode($data), then import it into Javascript.
You may notice I've done a slightly different structure to the one you requested, this one will look like this:
array('cats' => array('breed => 'siamese', 'colour' => 'white'), array('breed' => 'tabby', 'color' => 'mixed'));
I think it's easier to work with, but it should be easy enough to adjust if you really need it to be what you want it to be.

Related

Display Two tables data in Php

i have following tables
Author
id | author_name | author_detail | author_bio
books
id | author_id | book_name | book_detail
i want to display data in following way
Author Name ::
Author Detail ::
books :: 1.book1
2.book2
3.book3
4.book4
i have tried following query but didnt worked as per my requirement
select * from authors left join books on author.id=books.author_id
i have tried group concat but it gives books name with coma seperate.so i want to books detail in array
select author.author_name,author.author_detail,author.author_bio,group_concat(books.book_name) eft join books on author.id=books.author_id
i am expexting output like
Array
(
[0] => Array
(
[id] => 1
[name] => Norm
[books] => Array
(
[0] =>Array
(
[id] => 4
[book_name] => great wall
[created_at] => 2015-09-11 04:45:07
[updated_at] => 2015-09-11 04:45:07
)
[1] =>Array
(
[id] => 6
[book_name] =>new book
[created_at] => 2015-09-11 04:45:07
[updated_at] => 2015-09-11 04:45:07
)
)
)
[1] => Array
(
[id] => 2
[name] => Norm
[books] => Array
(
[0] =>Array
(
[id] => 2
[book_name] => amazing star
[created_at] => 2015-09-11 04:45:07
[updated_at] => 2015-09-11 04:45:07
)
[1] =>Array
(
[id] => 3
[book_name] =>way of journy
[created_at] => 2015-09-11 04:45:07
[updated_at] => 2015-09-11 04:45:07
)
)
)
i have checked this question also
displaying php mysql query result with one to many relationship
Can any one help me how to display data like above ?
thank you
Try this:
SELECT
A.id
A.author_name,
A.author_detail,
A.author_bio,
B.book_name,
B.created_at,
B.updated_at
FROM books AS B
LEFT JOIN author AS A
ON (A.id=B.author_id)
you will get result like this:
id | author_name | author_detail | author_bio | book_name
1 | ari | some detail | some bio | book_ari_1
1 | ari | some detail | some bio | book_ari_2
1 | ari | some detail | some bio | book_ari_3
2 | tester | some detail | some bio | book_tester_1
etc..
to make array as your expecting result you need to restructure your array result. i will asume your result array will be in $result variable
$new_result = array();
foreach ($result as $key => $value) {
if (empty($new_result[$value['id']]))
{
$new_result[$value['id']] = array(
'id' => $value['id'],
'name' => $value['name'],
'books' => array(
array(
'id' => $value['id'],
'book_name' => $value['book_name'],
'created_at' => $value['created_at'],
'updated_at' => $value['updated_at']
),
)
)
}
else
{
$new_result[$value['id']]['id'] = $value['id'];
$new_result[$value['id']]['name'] = $value['name'];
$new_result[$value['id']]['books'][] = array(
'id' => $value['id'],
'book_name' => $value['book_name'],
'created_at' => $value['created_at'],
'updated_at' => $value['updated_at']
);
}
}
the result will look like your expected. but the key number will be formated as id.
to reset key of $new_result as increment number you need to get only value use array_values() function
$new_result = array_values($new_result);
You could do it with your first query...but you'd have to check the author_id inside the record loop and show the author details only whenever the value changed (by comparing it with a value stored in a variable)...otherwise only show the book details.
So your code might (very roughly) look like this:
$query = "select whatever whatever...";
$records = $database->Execute($query);
foreach ($records as $fields) {
if ($fields['id'] != $previous_id) echo "Author ...";
echo "Book whatever whatever ...";
$previous_id = $fields['id'];
}
A more straightforward (although slightly longer) way would be to have a second query: a sub-query. And it would take place inside the loop through the results of the first (outer) query. So your outer query gets the authors and, after you show the author details, you have this separate query for books of the author...and you have a loop-within-the-outer-loop to show the details of each book.
So your code (very roughly) looks something like this:
$query = "select id, author_name, whatever from author";
$author_records = $database->Execute($query);
foreach ($author_records as $fields) {
echo "Author: {$fields['author_name']} whatever <br/>";
$subquery = "select whatever from books where id = whatever";
$book_records = $database->Execute($subquery);
foreach ($book_records as $otherfields) {
echo "Book whatever whatever";
}
}
you can do this in php no need to go in query itself but take both data in separate query i.e. books and author data
Remember i assumed $result as authors data and $result2 as books data
$item=array();
while($row=mysql_fetch_array($result))
{
$id=$row['id'];
$item[$id]['name']=$row['name'];
$item[$id]['id']=$row['id'];
$item[$id]['books']=array();
$temp=array();
while($row1=mysql_fetch_array($result2))
{
if($id==$row1['author_id'])
{
$temp['id']=$row1['id'];
$temp['book_name']=$row1['book_name'];
$temp['created_at']=$row1['created_at'];
$temp['updated_at']=$row1['updated_at'];
array_push($item['id']['books'],$temp);
}
}
}
Now here id is formatted as author's id. To get like array keys you can use array_values($item)

PHP MySQL Menu Sorting

Ok, so here's my table structure:
+--------------------------+ +----------------+ +-------------------------------+
| pages | | menus | | menu_pages |
+--------------------------+ +----+-----------+ +-------------------------------+
| id | title | slug | | id | name | | menu_id | page_id | parent_id |
+-------+---------+--------+ +----+-----------+ +---------+---------+-----------+
| 1 | Home | index | | 1 | default | | 1 | 1 | 0 |
+-------+---------+--------+ +----+-----------+ +---------+---------+-----------+
| 2 | About | about | | 2 | footer | | 1 | 2 | 0 |
+-------+---------+--------+ +----+-----------+ +---------+---------+-----------+
| 3 | Test 1 | test-1 | | 1 | 3 | 2 |
+-------+---------+--------+ +---------+---------+-----------+
| 4 | Test 2 | test-2 | | 1 | 4 | 2 |
+-------+---------+--------+ +---------+---------+-----------+
| 5 | Test 3 | test-3 | | 1 | 5 | 4 |
+-------+---------+--------+ +---------+---------+-----------+
So basically, we have pages, menus, and a menu_pages linking table which specifies the menu, the page, and the parent of each menu item.
Here's my query:
$query = "SELECT pages.id, pages.title, pages.slug, menu_pages.parent_id
FROM menus, pages, menu_pages WHERE menus.name = '$menu'
AND menus.id = menu_pages.menu_id
AND pages.id = menu_pages.page_id";
$results = $db->Query($query);
Here's the question: How do I get the menu items properly nested under their respective parents in an array? I've tried quite a few things already, but none of them worked beyond simply 2 levels, so I won't clutter up the question with it. Obviously I need some kind of recursion in PHP, or to modify my query maybe in a way that I can get the SQL to return them properly?
It should look something like this in the output:
[0] => array(
'id' => 1,
'title' => 'Home',
'slug' => '/',
'parent_id' => '0'
)
[1] => array(
'id' => 2,
'title' => 'About',
'slug' => 'about',
'parent_id' => 0,
'sub_menu' => array(
[0] => array(
'id' => 3,
'title' => 'Test 1',
'slug' => 'test-1',
'parent_id' => 2
)
[1] => array(
'id' => 4,
'title' => 'Test 2',
'slug' => 'test-2',
'parent_id' => '2',
'sub_menu' => array(
[0] => array(
'id' => 5,
'title' => 'Test 3',
'slug' => 'test-3',
'parent_id' => 4
)
)
)
)
)
Thanks for the help!
This isn't quite as simple as it first sounds - if you want to get into how to do it with SQL, you are looking for a recursive sql statement.
Unfortunately mysql doesn't support this directly, and you would need to write a body of code to get it working. There is an example of how to do it here. Not simple.
http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/
In case you're interested in how to pick this apart, you would implement it in Oracle like this:
SELECT p.id, p.title, p.slug, mp.parent_id, level
FROM menu_pages mp
JOIN pages p ON ( p.id = mp.page_id )
JOIN menus m ON ( m.id = mp.menu_id )
CONNECT BY PRIOR mp.page_id = mp.parent_id
START WITH ( m.name = 'default' AND mp.parent_id = 0 )
You are basically saying:
START WITH a query for the top level of the menu
CONNECT that back to the result set by joining the parent to the child
You end up with a result set like this:
id title slug parent level
------------------------------------
1 Home index 0 1
2 About about 0 1
3 Test 1 test-1 2 2
4 Test 2 test-2 2 2
5 Test 3 test-3 4 3
All this actually gives you in addition to what you already have is:
The "level" of each point in the menu.
If a sub menu appeared multiple times in your structure it would be repeated correctly.
Sections of the menu that are not connected properly will not be returned.
So, for small, simple and consistent menus it's probably over-kill anyway.
Plus, even in this case you would need to process this in PHP to get the structure you're looking for.
So, using that as inspiration you can see how you could implement it in mysql by just doing the post processing.
You start off with your original query:
SELECT pages.id
, pages.title
, pages.slug
, menu_pages.parent_id
FROM menus
, pages
, menu_pages
WHERE menus.name = 'default'
AND menus.id = menu_pages.menu_id
AND pages.id = menu_pages.page_id
You can then loop over this result and build the array structure yourself manually.
In order to avoid the problem of recursion, we're instead going to take advantage of the fact that we can have two variables pointing at the same data structure - we're going to use references so that changing the value of the variable in one reference will change the value of the variable in the other.
I.E. The difficulty you get is finding the right point in the hierarchy to add each child. With references you don't have to.
Create an empty menu array
Loop over the results from your SQL statement
Create a copy of each menu item and put it into a simply indexed store (by the id of the item)
If you have the root menu item, add it to your menu array (as a reference)
If you don't have the root menu item, find the parent in your simple store and add your new item to it.
At the end you should have the nice nested structure you're looking for.
Like this:
<?php
// As if it came back from mysql...
// Assumed that it's ordered so that every possible parent appears before all its childern
$aResults = array( array( 'id' => 1, 'title' => 'Home', 'slug' => 'index', 'parent_id' => 0 )
, array( 'id' => 2, 'title' => 'About', 'slug' => 'about', 'parent_id' => 0 )
, array( 'id' => 3, 'title' => 'Test 1', 'slug' => 'test-1', 'parent_id' => 2 )
, array( 'id' => 4, 'title' => 'Test 2', 'slug' => 'test-2', 'parent_id' => 2 )
, array( 'id' => 5, 'title' => 'Test 3', 'slug' => 'test-3', 'parent_id' => 4 ) );
// the menu you're creating
$aMenu = array();
// the simple store of the menu items you're going to use to find the parents
$aBaseMenuIndex = array();
foreach( $aResults as $aMenuItem ) {
$aMenuItem['sub_menu'] = array();
// add your menu item to the simple store
$aBaseMenuIndex[ $aMenuItem['id'] ] = $aMenuItem;
if ( $aMenuItem['parent_id'] == 0 ) {
// if it's a base menu item, add it to the menu
$aMenu[] =& $aBaseMenuIndex[ $aMenuItem['id'] ];
} else {
// if it's not a base item, add it to the sub menu, using the simply indexed store to find it
// adding it here will also add it to $aMenu, as $aMenu contains a reference to this
$aBaseMenuIndex[ $aMenuItem['parent_id'] ]['sub_menu'][] =& $aBaseMenuIndex[ $aMenuItem['id'] ];
}
}
var_dump( $aMenu );

How to sort a joined table with having the header just once in the output

I'm new with the codeigniter framework, and learning on how to use the MVC pattern. I'm trying to achieve an output but that isn't really working for me, allow me to illustrate my problem with the code:
I have 3 tables in my DB
CREATE TABLE carBrand
(
pk_brandID int,
brand varchar(255)
);
CREATE TABLE carModel
(
pk_modelID int,
model varchar(255)
)
CREATE TABLE brandModel
(
pk_brandmodelID int,
project varchar(255),
carOWner varchar(255),
buildyear varchar(255),
fk_brandID int,
fk_modelID int
)
At the moment I'm joing the tables with a join like this in my model
function getCarbyOwner(){
$this->db->join('carBrand', 'carBrand.pk_brandID = brandModel.fk_brandID');
$this->db->join('carModel', 'carModel.pk_modelID = brandModel.fk_modelID');
$this->db->where('carOwner', $$this->session->userdata('logged_in_owner'));
$q = $this->db->get('brandModel');
return $q->result();
}
That outputs this in my view - depending on which record is first in the db
brand 1
*model
brand 1
*model
brand 3
*model
brand 2
*model
brand 3
*model
But I am having difficulties with outputting the data
What I basically want is the following output
Brand 1
*model
*model
*model
Brand 2
*model
*model
*model
Brand 3
*model
*model
*model
This is my controller
function index(){
if($car= $this->car_model->getCarbyOwner()){
$data['car'] = $car;
$this->load->view('carview', $car);
}
}
The view:
if(isset($car)){
foreach($car as $r){
$r->brand;
$r->model
}
}
How can I achieve the result I want to have?
EDIT
I've implemented a few suggestions, but now it isn't outputting everything.
The records I have in the table brandModel are for example like this:
pk_brandmodelID | project | carowner | buildyear | fk_brandID | fk_modelID
1 | proj A | frank | 2012 | 1 | 6
2 | proj B | Jef | 2002 | 2 | 1
3 | proj C | jeffrey | 2013 | 1 | 5
4 | proj X | frank | 2010 | 2 | 2
5 | proj Y | george | 2008 | 1 | 3
Let's say brand 1 = audi and brand 2 is Mercedes
The wanted output is like this
Audi
model fk_id 6
model fk_id 5
model fk_id 3
Mercedes
model fk_id 1
model fk_id 2
But now I'm only getting
Audi
model fk_id 6
Mercedes
model fk_id 1
And I have used the following code:
Model
function getCarbyOwner(){
$this->db->join('carBrand', 'carBrand.pk_brandID = brandModel.fk_brandID');
$this->db->join('carModel', 'carModel.pk_modelID = brandModel.fk_modelID');
$this->db->where('carOwner', 'xxx');
$q = $this->db->get('brandModel');
if($result = $q->result())
{
foreach($result as $key => $value)
{
$d[$value->pk_brandID]['brand'] = $value->brand;
$d[$value->pk_brandID]['data'][$value->pk_modelID] = $value;
}
return $d;
}
else
return false;
}
View
if(isset($x)){
foreach($x as $r)
{
echo $r['brand']."<br />";
foreach($r['data'] as $v)
{
echo $v->model."<br />";
}
echo "<br />";
}
}
make new method into CAR modal
function getCarModels(){
$modalData = array();
$this->db->join('carBrand', 'carBrand.pk_brandID = brandModel.fk_brandID');
$this->db->where('carOwner', $$this->session->userdata('logged_in_owner'));
$q = $this->db->get('brandModel');
if($result = $query->result())
{
foreach($result as $key => $value)
{
$modalData[$value-pk_brandID[] = $value;
}
}
return $brandData;
}
and into controller file
$data['car'] = $this-car_modelgetCarModels();
and into view file
foreach($car as $r)
{
echo $r[0]->brand."<br />";
foreach($r as $v)
{
echo $v->model."<br />";
}
echo "<br />";
}
I think it would be easiest to get the resultset ordered, add something like this after the last ->where
$this->db->order_by("brandModel", "asc");
I'm not an expert on CodeIgniter, but the goal here is to get this appended to the SQL statement:
ORDER BY brand_name_col ASC, model_name_col ASC
Then it's just a matter of suppressing the display of "brand" when the value matches the preceding value.
You could either do it the way Spencer said - which is probably the easiest, least overhead way of doing it...
Or you could also group your result set into an Array of Arrays. Meaning you'll have to iterate through your resultset in the controller and put the corresponding values into the correct buckets.
e.g.
array Cars
( 'Brand1', array(..),
'Brand2', array(..),
...
)
and then iterate through nested loops in your UI.
You're iterating through an array of cars, echoing out each brand, and then each model. Even if you were to append an "order by" clause to your sql, it wouldn't change that.
You need to separate the cars out by brand, like dispake said.
foreach($car as $r)
{
if($r->brand = "Brand 1")
{
$brand1[] = $r->model;
}
else if($r->brand = "Brand 2")
etc etc....
That will leave you with 3 arrays, one for each brand, that you can then output as you please.
I would only use 2 tables instead of 3 like this:
CREATE TABLE carBrand
(
pk_brandID int,
brand varchar(255)
);
CREATE TABLE carModel
(
pk_modelID int,
fk_brandID int,
model varchar(255),
project varchar(255),
carOWner varchar(255),
buildyear varchar(255)
);
The query:
function getCarbyOwner($owner){
$q = $this->db->select('b.brand, m.model')
->from('carBrand b')
->join('carModel m', 'b.pk_brandID = m.fh_brandID')
->where('m.carOwner', $owner);
->group_by('b.brand')
->order_by('b.brand', 'ASC')
->get();
->result();
return $q;
}
Controller:
$owner = $this->session->userdata('logged_in_owner');
$data[cars] = $this->car_model->getCatbyOwner($owner);
$this->load->view('car_view', $data);
EDIT: 3 tables query:
function getCarbyOwner($owner){
$q = $this->db->select('b.brand, m.model, bm.carOwner')
->from('branModel bm')
->join('carModel m', 'm.pk_modelID = bm.fk_modelID')
->join('carBrand b', 'b.pk_brandID = bm.fk_brandID')
->where('bm.carOwner', $owner);
->group_by('b.brand')
->order_by('b.brand', 'ASC')
->get();
->result();
return $q;
}
Try the above if it works for you but just to let you know, JOINS are pretty expensive, at least more expensive then my first suggestion.
Frankly i agree with what Matteo T. says. Your tables seems to require another look into as i don't think the relationships between tables like that is efficient. Regardless, this is my answer.
your current model function isn't wrong actually, its just not sorted properly.
Model
function getCarbyOwner(){
$this->db->join('carBrand', 'carBrand.pk_brandID = brandModel.fk_brandID');
$this->db->join('carModel', 'carModel.pk_modelID = brandModel.fk_modelID');
$this->db->where('carOwner', 'frank'); // make sure the car owner is exists
$q = $this->db->get('brandModel');
if($result = $q->result())
{
foreach($result as $key => $value)
{
$d[$value->pk_brandID]['brand'] = $value->brand;
$d[$value->pk_brandID]['data'][$value->pk_modelID] = $value;
}
// test print_r($d); here to check the result
return $d;
}
else
return false;
}
View
if(isset($x)){
foreach($x as $r)
{
// test print_r($r); here to check the result
echo $r['brand']."<br />";
foreach($r['data'] as $v)
{
// test print_r($v); here to check the result
echo $v->model."<br />";
}
echo "<br />";
}
}
basically the idea is to change the standard result set into more suited array list, as suggested by dispake.
take note that my answer is just a sample. and probably does not suit your request completely.
ADDED-EDITS
the main idea of the sorting that i suggested is to sort the result set from (roughly something like this)
array(
[0] => array (
brandModelID => 1,
project => 'proj A',
carowner => 'frank',
buildyear => 2012,
brandID => 1,
modelID => 6,
),
[1] => array (
brandModelID => 2,
project => 'proj B',
carowner => 'frank',
buildyear => 2002,
brandID => 2,
modelID => 1,
),
[2] => array (
brandModelID => 3,
project => 'proj C',
carowner => 'frank',
buildyear => 2013,
brandID => 1,
modelID => 5,
),
[3] => array (
brandModelID => 4,
project => 'proj X',
carowner => 'frank',
buildyear => 2010,
brandID => 2,
modelID => 2,
),
[4] => array (
brandModelID => 5,
project => 'proj Y',
carowner => 'frank',
buildyear => 2008,
brandID => 1,
modelID => 3,
)
to
array(
[1] => array( // key is brandID
['brand'] => 'something',
['data'] array(
[6] => array ( // key is modelID
brandModelID => 1,
project => 'proj A',
carowner => 'frank',
buildyear => 2012,
brandID => 1,
modelID => 6,
),
[2] => array ( // key is modelID
brandModelID => 3,
project => 'proj C',
carowner => 'frank',
buildyear => 2013,
brandID => 1,
modelID => 5,
),
[4] => array ( // key is modelID
brandModelID => 5,
project => 'proj Y',
carowner => 'frank',
buildyear => 2008,
brandID => 1,
modelID => 3,
)
)
),
[2] => array( // key is brandID
['brand'] => 'something',
['data'] array(
[1] => array ( // key is modelID
brandModelID => 2,
project => 'proj B',
carowner => 'frank',
buildyear => 2002,
brandID => 2,
modelID => 1,
),
[3] => array ( // key is modelID
brandModelID => 4,
project => 'proj X',
carowner => 'frank',
buildyear => 2010,
brandID => 2,
modelID => 2,
)
)
)
no matter how i look, the function looks fine like this. There isn't any problem with the code. You only need to customize on what to show and what not to show. try using print_r() to check the results. I marked where you might need to check.

MySQL: fetch a row and multiple related rows - possible?

Let's say I have one table: "cars" with 3 fields: id, brand, cost.
There's a second table: "models" with 3 fields: id, brand, model_name.
Each "cars" row can have multiple related "models" rows.
Is it possible to do an sql-select whose output looks like this?
edit: I use PHP for the database querys
array(
[0] => array(
[id] => 1
[brand] => mercedes
[cost] => 1000
[models] => array(
[0] => array(
[id] => 1
[brand] => mercedes
[model_name] => slk
)
[1] => array(
[id] => 2
[brand] => mercedes
[model_name] => clk
)
[2] => array(
[id] => 3
[brand] => mercedes
[model_name] => whatever
)
)
)
)
You need to add a foreign key relation to the models table, say car_id. Then:
SELECT * FROM cars JOIN models ON car_id = models.id;
This will output something similar to what you are looking for.
Assuming you are using PHP, using the output:
$query= "SELECT * FROM cars JOIN models ON car_id = models.id";
$r= #mysqli_query($dbc, $query);
while ($row= mysqli_fetch_array($r, MYSQLI_ASSOC)) {
$carstuff['id']=$row[id];
$carstuff['brand']=$row[brand];
$carstuff['cost']=$row[cost];
$carstuff[$row['models']][]=$row['model_name'];
}
var_dump($carstuff);
Note, that the id, brand and cost are repeatedly overwritten, but that is okay because they are overwritten with the same information. I'm not too sure about the cleanliness of the code, but that is the basic idea.
Try this:
Query:
SELECT c.ID, c.brand,c.cost, GROUP_CONCAT(model_name SEPARATOR '","') as models
, GROUP_CONCAT(m.ID SEPARATOR ',') as MID
, GROUP_CONCAT(m.brand SEPARATOR '","') as mbrand
FROM cars c
LEFT OUTER JOIN model m
ON m.brand = c.brand
GROUP BY brand;
Output:
ID BRAND COST MODELS MID MBRAND
1 audi 1000 m11","m22 4,5 audi","audi
1 mercedes 1200 m1","m2","m3 1,2,3 mercedes","mercedes","mercedes
Now in your php code you can process the MODEL,MID and MBrand
(By using explode)
$modelArray = explode(" ,", $row["MODELS");
SQLFIDDLE

PHP MySQL joins and outputting as array

I was wondering if someone could help me please.
I have the following two tables, positions and polygons.
positions:
----------------------------------------------
| positionID | name | information
----------------------------------------------
| 1 | Southampton | text here
| 2 | London | text here
.
polygons:
-------------------------------------------------------------------
| polygonID | positionID | lat | lon
-------------------------------------------------------------------
| 1 | 1 | 434343.034343 | -43.4343434
| 2 | 1 | 343343.034343 | -43.4343434
| 3 | 1 | 434343.034343 | -54.4343434
I want to join the two tables and output them as an array in the following format.
$positions = array(
array( positionID => 1,
name => 'Southampton',
information => 'text here',
polys => array( array( Lat => 54.54299483853406,
Lng => -6.5224456787109375,
),
array( Lat => 54.648809788121866,
Lng => -6.405029296875,
),
array( Lat => 54.54020652089137,
Lng => -6.39129638671875,
),
),
),
);
I have wrote the following join statement however I'm really stuck on the next step.
SELECT * FROM (`positions`) LEFT JOIN `polygons` ON `positions`.`positionID` = `positions`.`positions`
The lat/lon data from the joins must be stored on the 'polys' key in the array.
Any help or advice would be much appreciated.
Thanks a million
If you have more than one polygonID per positionID, you going to fetch a lot of copies of positions.
I recommend to do 2 queries instead:
$positions = array();
$query_1 = "SELECT * FROM positions";
$query_2 = "SELECT * FROM polygons";
$resource_1 = mysql_query($query_1);
while($position = mysql_fetch_assoc($resource_1))
{
$positions[$position['positionID']] = $position;
$positions[$position['positionID']]['polys'] = array();
}
$resource_2 = mysql_query($query_2);
while($polygon = mysql_fetch_assoc($resource_2))
{
$positions[$polygon['positionID']]['polys'][$polygon['polygonID']]['Lat'] = $polygon['lat'];
$positions[$polygon['positionID']]['polys'][$polygon['polygonID']]['Lon'] = $polygon['lon'];
}
(Sorry for using deprecated functions like mysql_query in my exemple)
You only need one query, but you still need to do some processing with the result in PHP:
$sql = "SELECT * FROM positions
LEFT JOIN polygons ON positions.positionID = polygons.positionID";
$result = mysql_query($sql);
if (mysql_num_rows($result) > 0) {
$positions = array();
while ($row = mysql_fetch_assoc($result)) {
if (!isset($positions[$row['name']])) {
$positions[$row['name']] = array(
'positionID' => $row['positionID'],
'information' => $row['information'],
'polys' => array()
);
}
$positions[$row['name']]['polys'][] = array(
'lat' => $row['lat'],
'lon' => $row['lon']
);
}
print_r($positions);
}
This will also return positions which don't actually have any polygon information. To prevent that, simply change the LEFT JOIN to JOIN.
As for which is most efficient, I'm afraid I don't know the answer to that. Best bet is to benchmark both this method and the one advised by Puggan Se if you can.

Categories