我正在查询数据库以检索包含一对多关系的一些信息。考虑:
CREATE TABLE `movies` (
`id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(50) NOT NULL,
`desc` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
INSERT INTO `movies` VALUES ('1', 'The Princess Bride', 'A fantastic film of epic adventure, action, and love.');
CREATE TABLE `showtimes` (
`movie_id` int(10) unsigned NOT NULL,
`showtime_id` int(10) unsigned NOT NULL auto_increment,
`starttime` timestamp NOT NULL,
PRIMARY KEY (`movie_id`,`showtime_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `showtimes` VALUES ('1', '1', '2011-09-19 20:00:00'), ('1', '2', '2011-09-19 23:00:00'), ('1', '3', '2011-09-20 13:00:00');
我希望收到信息的方式是这样的。
$movies[1] = array(
'id' => 1,
'title' => 'The Princess Bride',
'desc' => 'A fantastic film of epic adventure, action, and love.',
'showtimes' => array(
'1' => '2011-09-19 20:00:00',
'2' => '2011-09-19 23:00:00',
'3' => '2011-09-20 13:00:00'));
这似乎是我查看数据最明智的方式。如果我打印剧院的所有放映时间,我可以做一些简单的事情:
foreach($movies as $movie)
{
//pretend there's style stuff here
echo $movie['title'] . "&mdash" . $movie['desc'];
foreach($movie['showtime'] as $time)
{
if ($time > $_SERVER['REQUEST_TIME'])
{
echo $time;
}
}
}
不幸的是,这不是我从标准查询中得到的。类似的东西:
SELECT * FROM `movies` INNER JOIN `showtimes` ON `movies`.`id` = `showtimes`.`movie_id`;
收率:
$movies[1] = array('id' => 1, 'title' => 'The Princess Bride', 'desc' => 'A fantastic film of epic adventure, action, and love.', 'starttime' => '2011-09-19 20:00:00');
$movies[2] = array('id' => 1, 'title' => 'The Princess Bride', 'desc' => 'A fantastic film of epic adventure, action, and love.', 'starttime' => '2011-09-19 23:00:00');
$movies[3] = array('id' => 1, 'title' => 'The Princess Bride', 'desc' => 'A fantastic film of epic adventure, action, and love.', 'starttime' => '2011-09-20 13:00:00');
这不是我想要的。在具有更多数据的较大结果集中,我也对返回如此多的重复数据的效果感到有些好奇(考虑使用数十个连接的更宽行)。
我知道我可以使用像GROUP_CONCAT()
之类的构造来将这些放映时间附加在一起,但是我稍后会将它们分开。对于像时间戳这样简单的事情,它很容易,因为我可以选择不会以该格式出现的分隔符,如果我分割评论,例如它会有点难度。
我可以做一些蹩脚的事情,例如遍历所有电影,从该循环中查询放映时间,但是没有办法将 web scale 。
我可以在查询中执行连接,然后迭代这些结果并附加重复的主键,但这似乎也缺乏优雅。
问题
是否有优雅的方式来获取我正在寻找的东西?在这个特定的应用程序中,我正在使用Zend Framework,如果它内置于那个非常敏锐的那个(或另一个框架)中。
感谢
答案 0 :(得分:1)
在两个表上进行某种连接(您的选择),然后遍历结果。
$query = "SELECT * FROM movies LEFT JOIN showtimes ON showtimes.movie_id = movies.id";
$result = $db->query($query);
while($row = $result->fetch()){
if(isset($movies[$row['id']])
$movies[$row['id']]['showtimes'][] = $row['starttime'];
else{
$movies[$row['id']] = array(
'id'=>$row['id'],
'title'=>$row['title'],
'desc'=>$row['desc'],
'showtimes'=>array($row['starttime'])
);
}
}