MySQL加入了一对多的表关系

时间:2011-11-05 21:12:24

标签: mysql

我不知道这是否可行但在MySQL中有一种方法可以生成单个查询,其中一对多表连接的多个结果可以设置为一个项的结果键上的数组?

我意识到这个问题不是很清楚,所以我会解释一下我的事情:

首先,我目前正在使用隐式连接,并希望了解有关显式连接的更多信息(我目前知道的很少),也许这些可以提供我正在寻找的答案?

例如给出两个表:

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`)
)

表b中有许多条目与表a中的单个条目相关。

如果我要运行以下查询:

SELECT a.*, b.* FROM a, b WHERE b.id_a = a.id_a AND a.id_a = x;

我会得到一个包含多个条目的数组,其中重复了单项id x的数据。我真正想要的是从表a返回的单行,其中一个键定义为b,其中包含表b中多个匹配条目的数组。我怀疑单独使用查询是不可能的,但如果是这样的话会很好。目前我在PHP中执行以下操作(其中$ this-> _db是Zend Framework数据库适配器)。这会运行很多查询!:

$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']);
}

或者我可以使用我原来的连接查询和后期处理,我怀疑它更有效,但意味着我需要明确地复制我需要的列(痛苦而且远非优雅):

$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;
}

2 个答案:

答案 0 :(得分:1)

您的查询使用隐式JOIN

SELECT a.*
     , b.* 
FROM a, b 
WHERE b.id_a = a.id_a 
  AND a.id_a = x

使用明确的JOIN

SELECT a.*
     , b.* 
FROM a
  JOIN b
    ON b.id_a = a.id_a 
WHERE a.id_a = x

在一个查询中使用数据的一种方法是使用 GROUP_CONCAT() 功能。但它可能不是您可以使用的格式:

SELECT a.*
     , GROUP_CONCAT( b.id_b
                     ORDER BY b.id_b ASC
                     SEPARATOR ',' 
                   ) AS b_ids
     , GROUP_CONCAT( b.b_column1 
                     ORDER BY b.id_b ASC
                     SEPARATOR ',' 
                   ) AS b_column1s
     , ...                            --- etc
FROM a
  JOIN b
    ON b.id_a = a.id_a 
WHERE a.id_a = x
GROUP BY a.id_a

答案 1 :(得分:0)

你可能正在寻找一个ORM(对象关系映射器),它可以处理对象之间的关联,并且能够返回一个包含B对象数组的A对象。

请参阅Good PHP ORM Library?

使用显式连接,查询将如下所示:

SELECT a.*, b.* FROM a inner join b on b.id_a = a.id_a where a.id_a = x;