sql >> Databasteknik >  >> RDS >> Mysql

Fråga efter inlägg och taggar i samma fråga

Det är bättre om du inte väljer en group_concat lösning eftersom den inte är tillförlitlig på grund av teckenlängden har den en standardgräns på 1024 tecken att sammanfoga men den kan ökas vilket definieras i manual men du kan inte helt förlita dig på en definierad gräns istället, du kan hantera det i ditt applikationslager (php) som att du hämtar data och någonstans du vill visa inlägg och dess relaterade taggar kan du fortfarande använda din sökfråga med ordning efter inlägg nu varje inlägg kan ha mer än en tagg så att resultatuppsättningen kommer att ha dubbletter av inläggsdata på grund av att varje inläggsrad kommer att ha en tagg och en annan rad med samma inlägg kommer att ha andra tagg och så vidare nu när du går igenom dina resultat visar varje inlägg bara en gång lägger till en kontroll

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

I ovanstående fråga har jag lagt till t.* för att välja alla inlägg och dess relaterade taggar nu i loop $currentParent kommer att ha ett tidigare inläggs-id i loop kontrollera om det är samma inlägg och visa sedan dess taggar om villkoret returnerar falskt då är det ett nytt inlägg som visar inläggsrubrik med hjälp av markering (h1), jag har valt alla kolumner från båda tabellerna men du ska bara lägga till behövs kolumner från taggtabellen och om post och taggtabell har kolumner med samma namn så definierade frågan dem med olika 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>'; 
    ...
}

Den resulterande uppmärkningen blir som

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

Om du inte visar data och du använder den någon annanstans (webbtjänst), använd fortfarande en sammanfogad fråga och omvandla din data genom att skapa array/objekt varje inlägg har en array av sina relaterade taggar ungefär som nedan

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

det finns ett annat sätt som inte rekommenderas få inlägg och i loop få taggar genom att köra frågan nu kommer den här lösningen att fungera men kommer att involvera oönskade frågor så att det kommer att köras en extra fråga för varje inlägg.

Om du nu verkligen vill hålla fast vid group_concat sätt att svara på din fråga I'm not sure if I can trust the order? det finns också ett sätt att lägga till order by i group_concat så att de resulterande sammanlänkade taggarna kommer att ordnas och för den andra kolumnen kan du sätta samma ordningskriterier

$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. Skapa en sekvens för ett varchar2-fält i Oracle

  2. postgresql saknar stöd för parameterizd-frågor

  3. föreslå ett postgres-verktyg för att hitta skillnaden mellan schemat och data

  4. ORDER BY RAND() verkar vara mindre än slumpmässigt