I have no idea if this is possible but is there a way in MySQL to produce a single query where the multiple results of a one to many table join can be set as an array on a key of the result for the one item?
I realise that question isn't very clear so I'll explain what I'm after further:
Firstly, I'm currently using implicit joins and would like to learn more on explicit joins (of which I currently know very little), perhaps these could provide the answer I'm looking for?
For example given two tables:
CREATE TABLE `a` (
`id_a` int(11) NOT NULL AUTO_INCREMENT,
`a_column1` varchar(255) NOT NULL,
...
PRIMARY KEY (`id_a`)
)
CREATE TABLE `b` (
`id_b` int(11) NOT NULL AUTO_INCREMENT,
`id_a` int(11) NOT NULL,
`b_column1` varchar(255) NOT NULL,
...
PRIMARY KEY (`id_b`)
)
Where table b has many entries related to a single entry in table a.
If I were to run the following query:
SELECT a.*, b.* FROM a, b WHERE b.id_a = a.id_a AND a.id_a = x;
I would get an array with multiple entries with the data of the single item id x repeated. What I actually want is a single row returned from table a
with a key defined as b
which contains an array of the multiple matching entries from table b
. I suspect that this is not possible with a query alone, but it would be great if it was. Currently I am doing the following in PHP (where $this->_db is a Zend Framework database adapter). This runs a lot of queries!:
$query = "SELECT * FROM a WHERE id_a = ?";
$items = $this->_db->fetchAll($query, $id);
foreach($items as $key => $item) {
$query = "SELECT * FROM b WHERE id_a = ?";
$items[$key]['b'] = $this->_db->fetchAll($query, $item['id']);
}
Alternatively I can use my original join query and post process, which I suspect is more efficient, but means I need to explicitly copy over the columns I need (a pain and far from elegant):
$query = "SELECT * FROM a, b WHERE a.id_a = b.id_a AND a.id_a = ?";
$items = $this->_db->fetchAll($query, $id);
$output = array('a_column1' => $items[0]['a_column1'], etc...);
$output['b'] = array();
foreach($items as $item) {
$b = array('b_column1' => $item['b_column1'], etc...);
$output['b'][] = $b;
}