sql >> Database >  >> RDS >> Mysql

Query voor post en tags in dezelfde query

Het is beter als je niet kiest voor een group_concat oplossing omdat het niet betrouwbaar is vanwege de tekenlengte, het heeft een standaardlimiet van 1024 tekens om samen te voegen, maar het kan worden verhoogd, wat is gedefinieerd in handleiding maar u kunt niet volledig vertrouwen op een gedefinieerde limiet, in plaats daarvan kunt u deze verwerken in uw applicatielaag (php) alsof u gegevens ophaalt en ergens waar u berichten en de bijbehorende tags wilt weergeven. kan meer dan één tags hebben, dus de resultatenset heeft dubbele berichtengegevens omdat elke postrij één tag heeft en een andere rij met dezelfde post een tweede tag enzovoort. een vinkje toevoegen

$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();

In bovenstaande zoekopdracht heb ik t.* . toegevoegd om alle berichten en de bijbehorende tags nu in een lus te selecteren $currentParent zal een vorig bericht-ID in een lus hebben, controleer of het hetzelfde bericht is en geef dan de tags weer als de voorwaarde false retourneert, dan is het een nieuw bericht toon de berichtkop met behulp van opmaak (h1), ik heb alle kolommen uit beide tabellen geselecteerd, maar je moet alleen toevoegen wat nodig is kolommen uit de tabel met tags en als de post- en tagtabel kolommen met dezelfde naam hebben, definieerde u ze in de query met een andere alias

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

Resulterende opmaak zal zijn als

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

Als je geen gegevens weergeeft en je gebruikt het ergens anders (webservice), gebruik dan nog steeds één samengevoegde query en transformeer je gegevens door een array/object te maken. Elk bericht heeft een array van zijn gerelateerde tags, zoiets als hieronder

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

er is een andere manier die ten zeerste niet wordt aanbevolen ontvang berichten en haal tags in een lus door een query uit te voeren. Deze oplossing zal het werken, maar zal ongewenste query's met zich meebrengen, zodat er voor elk bericht een extra query wordt uitgevoerd.

Als je nu echt bij group_concat wilt blijven benadering om uw vraag te beantwoorden I'm not sure if I can trust the order? er is ook een manier om order by toe te voegen in group_concat zodat de resulterende aaneengeschakelde tags worden geordend en voor de tweede kolom kunt u dezelfde bestelcriteria invoeren

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


  1. Oracle ODP.NET-verbindingsreeks:wat gaat er in Data Source?

  2. Hoe voorbereide verklaring in heroku met postgres-database uit te schakelen?

  3. Hoe te ontsnappen aan onderstrepingstekens in de tekenreeksquery in slaapstand en SQL?

  4. MySQL-back-up en herstel vanaf de opdrachtregel