¿Cómo manejar una relación correctamente con PHP y MySQL?
Pregunta
Tengo 3 tablas:
+-----------------+ | validations | +----+-------+----+ | id | param | ... +----+-------+
+------------------+ | replacements | +----+-------------+ | id | replacement | +----+-------------+
+--------------------------------+ | validations-replacements | +---------------+----------------+ | validation_id | replacement_id | +---------------+----------------+
Ahora estoy ejecutando mi consulta SQL en esas mesas (con uniones, por supuesto). Y lo que recibo en PHP es sth. como eso:
... [6] => stdClass Object ( [id] => 11 [search_param] => Dänische Belletristik [replacement] => Denmark ) [7] => stdClass Object ( [id] => 11 [search_param] => Dänische Belletristik [replacement] => Fiction ) ...
Ahora, en mi matriz PHP tengo los mismos 'Search_param' e 'ID' varias veces. Eso apesta por imprimirlo en la pantalla. Podría agrupar los datos por 'ID' para evitar eso, pero solo tengo el valor de 1 'reemplazo' disponible.
Lo que estoy buscando sería un resultado como este:
... [7] => stdClass Object ( [id] => 11 [search_param] => Dänische Belletristik [replacement] => array(Denmark, Fiction) ) ...
Lo que quiero saber: ¿es eso posible con la estructura de mi mesa simplemente arreglando la consulta? ¿O tengo que preocuparme por eso en mi código PHP, si es así: alguna pisa de cómo hacerlo mejor? Hay muchos datos ... ¿es correcta la estructura de mi tabla? Todavía estoy un poco incierto cuando se trata de bases de datos ...
Saludos.
Solución
¿Parece que quieres mostrar todos los reemplazos para un cierto parámetro de búsqueda? Asumir que su consulta es algo así como:
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'
Puede agruparlos en PHP jugando con la matriz de resultados, suponiendo que su objeto de resultados sea $results
:
$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
O puede hacerlo en MySQL, solo iterar sobre el resultado en 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
Con GROUP_CONCAT
Obtendrá toda una sola línea de resultados para cada parámetro de búsqueda, y todos sus reemplazos en una cadena separada por comas, con la que luego puede trabajar fácilmente iterar sobre el resultado en PHP:
$replacements = array() ;
foreach ($results as $result) {
$currSearchParam = $result['search_param'];
$currReplacements = $result['replacements'] ;
$replacements[$currSearchParam] = explode(',', $currReplacements) ;
}
Otros consejos
Parece que podrías usar GROUP_CONCAT