sql >> Databáze >  >> RDS >> Mysql

Dotaz na příspěvek a značky ve stejném dotazu

Je lepší, když nevyhledáváte group_concat řešení, protože není spolehlivé kvůli délce znaků, má výchozí limit 1024 znaků ke zřetězení, ale lze jej zvýšit, což je definováno v příručka ale nemůžete se plně spolehnout na definovaný limit místo toho můžete s ním zacházet ve vaší aplikační vrstvě (php), jako byste načítali data a někde, kde chcete zobrazit příspěvky a související značky, můžete stále použít svůj spojovací dotaz s pořadím podle příspěvků nyní každý příspěvek může mít více než jeden štítek, takže sada výsledků bude mít duplicitní data příspěvků, protože každý řádek příspěvku bude mít jeden štítek a další řádek se stejným příspěvkem bude mít druhý štítek a tak dále, když procházíte výsledky, zobrazte každý příspěvek pouze jednou přidání nějaké kontroly

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

Ve výše uvedeném dotazu jsem přidal t.* pro výběr všech příspěvků a souvisejících tagů, které jsou nyní ve smyčce $currentParent bude mít ve smyčce zkontrolováno ID předchozího příspěvku, zda se jedná o stejný příspěvek, poté zobrazí jeho značky, pokud podmínka vrátí hodnotu false, pak se u nového příspěvku zobrazí záhlaví příspěvku pomocí značky (h1), vybral jsem všechny sloupce z obou tabulek, ale měli byste přidat pouze potřebné sloupce z tabulky tagů a pokud mají post a tag tabulka sloupce stejného jména, pak je v dotazu definovali s jiným aliasem

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

Výsledné označení bude jako

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

Pokud data nezobrazujete a používáte je někde jinde (webová služba), pak stále použijte jeden spojený dotaz a transformujte svá data vytvořením pole/objektu, každý příspěvek má pole souvisejících značek něco jako níže

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

existuje další způsob, který se vřele nedoporučuje získat příspěvky a ve smyčce získat značky spuštěním dotazu nyní toto řešení bude fungovat, ale bude zahrnovat nežádoucí dotazy, takže pro každý příspěvek bude proveden zvláštní dotaz.

Nyní, pokud opravdu chcete zůstat u group_concat přístup k odpovědi na vaši otázku I'm not sure if I can trust the order? existuje také způsob, jak přidat order by v group_concat takže výsledné zřetězené značky budou seřazeny a pro druhý sloupec můžete zadat stejná kritéria řazení

$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. Problém s php seznamem objednávek / while loop

  2. Tipy a triky pro navigaci v komunitě PostgreSQL

  3. Jak používat automatický přírůstek v typu dat Varchar v PHP a MYSQL?

  4. Spusťte klienta Oracle v 32bitovém režimu na 64bitovém počítači