如何正确处理PHP和MySQL的n:m关系?

时间:2011-01-25 21:57:33

标签: php mysql database join nm

我有3张桌子:

+-----------------+
|   validations   |
+----+-------+----+
| id | param | ...
+----+-------+
+------------------+
|   replacements   |
+----+-------------+
| id | replacement |
+----+-------------+
+--------------------------------+
|    validations-replacements    |
+---------------+----------------+
| validation_id | replacement_id |
+---------------+----------------+

现在我在那些表上运行我的SQL查询(当然还有连接)。我用PHP收到的是......那样:

...
[6] => stdClass Object
(
    [id] => 11
    [search_param] => Dänische Belletristik
    [replacement] => Denmark
)

[7] => stdClass Object
(
    [id] => 11
    [search_param] => Dänische Belletristik
    [replacement] => Fiction
)
...

现在,在我的PHP-Array中,我多次获得相同的'search_param'和'id'。这很难将它打印到屏幕上。我可以通过'id'对数据进行分组以避免这种情况,但之后我只能获得1'替换'值。

我正在寻找的是这样的结果:

...
[7] => stdClass Object
(
    [id] => 11
    [search_param] => Dänische Belletristik
    [replacement] => array(Denmark, Fiction)
)
...

我想知道的是:通过修复查询,我的表结构是否可以实现?或者我必须在我的PHP代码中关心它 - 如果是这样:任何提示如何做到最好?有足够的数据...... 我的桌子结构是否正确?在数据库方面,我仍然有点不确定......

最好的问候。

2 个答案:

答案 0 :(得分:1)

看起来你想显示某个搜索参数的所有替换?假设您的查询类似于:

SELECT * 
FROM validations_replacements vr 
INNER JOIN validations v ON v.id = vr.validation_id 
INNER JOIN replacements r ON r.id = vr.replacement_id
WHERE v.param = '$search_param'

假设您的结果对象为$results,您可以通过使用结果数组在PHP中对它们进行分组:

$replacements = array() ;
foreach ($results as $result) {
    $currSearchParam = $result['search_param'];
    $currReplacement = $result['replacement'] ;
    if (!isset($replacements[$currSearchParam])) {
        $replacements[$currSearchParam] = array() ;
    }
    $replacements[$currSearchParam][] = $currReplacement;
}

//I'll let you fill in the blanks like object id or naming the array keys as you wish

或者你可以在mysql中完成,然后在PHP中迭代结果:

SELECT v.id, v.param, GROUP_CONCAT(r.replacement)
FROM validations_replacements vr 
INNER JOIN validations v ON v.id = vr.validation_id 
INNER JOIN replacements r ON r.id = vr.replacement_id
WHERE v.param = '$search_param'
GROUP BY v.id

使用GROUP_CONCAT,您将获得每个搜索参数的所有单个结果行,以及逗号分隔字符串中的所有替换,然后您可以通过在PHP中迭代结果来轻松处理:

$replacements = array() ;
foreach ($results as $result) {
    $currSearchParam = $result['search_param'];
    $currReplacements = $result['replacements'] ;
    $replacements[$currSearchParam] = explode(',', $currReplacements) ;
}

答案 1 :(得分:0)

看起来您可以使用GROUP_CONCAT