sql >> Database teknologi >  >> RDS >> Mysql

Forespørgsel efter indlæg og tags i samme forespørgsel

Det er bedre, hvis du ikke går efter en group_concat løsning, fordi den ikke er pålidelig på grund af tegnlængde, har den en standardgrænse på 1024 tegn til sammenkædning, men den kan øges, hvilket er defineret i manual men du kan ikke stole fuldt ud på defineret grænse, i stedet kan du håndtere det i dit applikationslag (php), som om du henter data, og et sted du vil vise indlæg og dets relaterede tags, kan du stadig bruge din deltagelsesforespørgsel med rækkefølge efter indlæg nu hvert indlæg kan have mere end ét tag, så resultatsættet vil have duplikerede indlægsdata på grund af, at hver postrække vil have ét tag, og en anden række med samme post vil have et andet tag og så videre nu, når du går gennem dine resultater, viser hvert indlæg kun én gang tilføjer en kontrol

$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 ovenstående forespørgsel har jeg tilføjet t.* for at vælge alle indlæg og dets relaterede tags nu i loop $currentParent vil have et tidligere indlægs-id i løkke, tjek om det er samme indlæg, så vis dets tags, hvis betingelsen returnerer falsk, så er det en ny postvisningsoverskrift ved brug af markup (h1), jeg har valgt alle kolonner fra begge tabeller, men du skal kun tilføje nødvendige kolonner fra tags-tabellen, og hvis post- og tag-tabellen har kolonner med samme navn, definerede forespørgslen dem med et andet 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 opmærkning vil være som

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

Hvis du ikke viser data, og du bruger det et eller andet sted (webservice), så brug stadig én samlet forespørgsel og transformer dine data ved at oprette array/objekt, hvert indlæg har en række af dets relaterede tags noget som nedenfor

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

der er en anden måde, som ikke anbefales få indlæg og i loop få tags ved at køre forespørgsel nu vil denne løsning fungere, men vil involvere uønskede forespørgsler, så der vil blive udført en ekstra forespørgsel for hvert indlæg.

Hvis du nu virkelig vil holde dig til group_concat tilgang til at besvare dit spørgsmål I'm not sure if I can trust the order? der er også en måde, du kan tilføje order by i group_concat så de resulterende sammenkædede tags vil blive ordnet, og for anden kolonne kan du sætte samme rækkefølgekriterier

$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. MySQL-filter på mange-til-mange

  2. At bruge en anden tabel som et WHERE-kriterie i SQL

  3. Datagenerering og hardwarekvalitet

  4. php oci8 ext indlæses ikke Kan ikke indlæse dynamisk bibliotek