Lepiej, jeśli nie wybierzesz group_concat
rozwiązanie, ponieważ nie jest niezawodne ze względu na długość znaków, ma domyślny limit 1024 znaków do łączenia, ale można go zwiększyć, co jest zdefiniowane w podręcznik
ale nie możesz w pełni polegać na zdefiniowanym limicie, zamiast tego możesz obsłużyć to w swojej warstwie aplikacji (php), tak jak pobierasz dane i gdzieś, gdzie chcesz wyświetlić posty i powiązane tagi, nadal możesz użyć zapytania dołączającego z kolejnością postów teraz każdy post może mieć więcej niż jeden tag, więc zestaw wyników będzie zawierał zduplikowane dane postów, ponieważ każdy wiersz postu będzie miał jeden tag, a inny wiersz z tym samym postem będzie miał drugi tag i tak dalej, gdy przeglądasz wyniki, wyświetlaj każdy post tylko raz przez dodanie czeku
$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();
W powyższym zapytaniu dodałem t.*
aby zaznaczyć wszystkie posty i powiązane z nim tagi teraz w pętli $currentParent
będzie miał identyfikator poprzedniego posta w pętli sprawdź, czy jest to ten sam post, a następnie wyświetl jego tagi, jeśli warunek zwraca wartość fałsz, wtedy jest to nowy nagłówek posta, wyświetl post za pomocą znaczników (h1), zaznaczyłem wszystkie kolumny z obu tabeli, ale powinieneś dodać tylko potrzebne kolumny z tabeli tagów i jeśli post i tabela tagów mają kolumny o tej samej nazwie to w zapytaniu zdefiniowano je z innym 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>';
...
}
Wynikowy znacznik będzie taki jak
<h1>Post title 1</h1>
<p>tag 1</p>
<p>tag 2</p>
<h1>Post title 2</h1>
<p>tag 3</p>...
Jeśli nie wyświetlasz danych i używasz ich w innym miejscu (usługa internetowa), nadal użyj jednego połączonego zapytania i przekształć swoje dane, tworząc tablicę/obiekt, każdy post ma tablicę powiązanych tagów, jak poniżej
$posts =array();
foreach ($results as $post) {
$posts[$post->id]['title'] = $post->title;
$posts[$post->id]['tags'][] =array('id' => $tag->id ,'name' =>$post->name);
}
istnieje inny sposób, który nie jest zalecany pobierz posty i w pętli pobierz tagi, uruchamiając zapytanie, teraz to rozwiązanie będzie działać, ale będzie obejmować niechciane zapytania, dzięki czemu dla każdego postu zostanie wykonane dodatkowe zapytanie.
Teraz, jeśli naprawdę chcesz pozostać przy group_concat
podejście do odpowiedzi na Twoje pytanie I'm not sure if I can trust the order?
istnieje również sposób na dodanie order by
w group_concat
aby wynikowe połączone tagi były uporządkowane, a dla drugiej kolumny można umieścić te same kryteria porządkowania
$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');