sql >> Base de Datos >  >> RDS >> Mysql

Consulta de publicación y etiquetas en la misma consulta

Es mejor si no busca un group_concat solución porque no es confiable debido a la longitud de los caracteres, tiene un límite predeterminado de 1024 caracteres para concatenar, pero se puede aumentar, lo cual se define en manual pero no puede confiar completamente en el límite definido, sino que puede manejarlo en su capa de aplicación (php) como si estuviera obteniendo datos y en algún lugar donde desea mostrar publicaciones y sus etiquetas relacionadas, aún puede usar su consulta de unión con orden por publicaciones ahora cada publicación puede tener más de una etiqueta, por lo que el conjunto de resultados tendrá datos de publicaciones duplicadas debido a que cada fila de publicación tendrá una etiqueta y otra fila con la misma publicación tendrá una segunda etiqueta y así sucesivamente ahora, cuando recorra los resultados, muestre cada publicación solo una vez por añadiendo algún cheque

$this->db->select('p.*,t.*');
$this->db->from('posts p');
$this->db->join('tags_map tm', 't.id_post = p.id');
$this->db->join('tags t', 't.id = tm.id_tag');
$this->db->order_by('p.id asc,t.id asc');
$results = $this->db->get();

En la consulta anterior, he agregado t.* para seleccionar todas las publicaciones y sus etiquetas relacionadas ahora en bucle $currentParent tendrá una identificación de publicación anterior en bucle, verifique si es una misma publicación, luego muestre sus etiquetas si la condición devuelve falso, entonces es una nueva publicación que muestra el encabezado de la publicación usando marcado (h1), he seleccionado todas las columnas de ambas tablas, pero debe agregar solo lo necesario columnas de la tabla de etiquetas y si la publicación y la tabla de etiquetas tienen columnas con el mismo nombre, entonces en la consulta las definió con un alias diferente

$currentParent = false;
foreach ($results as $post) {
    if ($currentParent != $post->id) {
        echo '<h1>' . $post->title . '</h1>';
        $currentParent = $post->id;
    }
    echo '<p>' . $post->name . '</p>'; /** here list tags info*/
    echo '<p>' . $post->tag_other_details . '</p>'; 
    ...
}

El marcado resultante será como

<h1>Post title 1</h1>
    <p>tag 1</p>
    <p>tag 2</p>
<h1>Post title 2</h1>
    <p>tag 3</p>...

Si no está mostrando datos y los está usando en algún otro lugar (servicio web), use una consulta unida y transforme sus datos creando una matriz/objeto, cada publicación tiene una matriz de sus etiquetas relacionadas, algo como a continuación

$posts =array();
foreach ($results as $post) {
 $posts[$post->id]['title'] = $post->title;
 $posts[$post->id]['tags'][] =array('id' => $tag->id ,'name' =>$post->name);
}

hay otra forma que es muy no recomendada obtenga publicaciones y en bucle obtenga etiquetas ejecutando la consulta ahora, esta solución funcionará, pero implicará consultas no deseadas, por lo que se ejecutará una consulta adicional para cada publicación.

Ahora, si realmente quieres quedarte con group_concat enfoque para responder a su pregunta I'm not sure if I can trust the order? también hay una manera de agregar order by en group_concat para que las etiquetas concatenadas resultantes se ordenen y para la segunda columna puede poner el mismo criterio de ordenación

$this->db->select('p.*,group_concat(t.name order by t.id) as thetags,
                       group_concat(t.relevance order by t.id) as therelevances');
$this->db->from('posts p');
$this->db->join('tags_map tm', 't.id_post = p.id');
$this->db->join('tags t', 't.id = tm.id_tag');
$this->db->group_by('p.id');