Mysql
 sql >> база данни >  >> RDS >> Mysql

Заявка за публикация и етикети в същата заявка

По-добре е, ако не изберете group_concat решение, тъй като не е надеждно поради дължината на символа, има ограничение по подразбиране от 1024 знака за свързване, но може да бъде увеличено, което е дефинирано в ръководство но не можете напълно да разчитате на дефиниран лимит, вместо това можете да се справите с него във вашия приложен слой (php), сякаш извличате данни и някъде искате да показвате публикации и свързаните с тях тагове, все още можете да използвате вашата заявка за присъединяване с ред по публикации сега всяка публикация може да има повече от един тагове, така че резултатният набор ще има дублирани данни за публикации, тъй като всеки ред на публикация ще има един таг, а друг ред със същата публикация ще има втори таг и така нататък сега, когато преглеждате резултатите си, показвайте всяка публикация само веднъж чрез добавяне на чек

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

В горната заявка добавих t.* за да изберете цялата публикация и свързаните с нея тагове сега в цикъл $currentParent ще има идентификатор на предишна публикация в цикъл, проверете дали е същата публикация, след това покажете нейните етикети, ако условието върне false, тогава е нова публикация, покажете заглавието на публикацията, използвайки маркиране (h1), избрах всички колони от двете таблици, но трябва да добавите само необходимите колони от таблицата с етикети и ако публикацията и таблицата с етикети имат колони с едно и също име, тогава в заявката те са дефинирани с различен псевдоним

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

Резултатното маркиране ще бъде като

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

Ако не показвате данни и ги използвате някъде другаде (уеб услуга), тогава все пак използвайте една обединена заявка и трансформирайте данните си, като създадете масив/обект, всяка публикация има масив от свързаните с нея тагове, нещо като по-долу

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

има друг начин, който силно не се препоръчва получаване на публикации и в цикъл получаване на етикети чрез стартиране на заявка сега това решение ще работи, но ще включва нежелани заявки, така че ще има допълнителна заявка, изпълнена за всяка публикация.

Сега, ако наистина искате да се придържате към group_concat подход за отговор на вашия въпрос I'm not sure if I can trust the order? има и начин да добавите order by в group_concat така че получените свързани етикети да бъдат подредени и за втората колона можете да поставите същите критерии за подреждане

$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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL произвежда колони с цикъл в израз за избор

  2. Присъединете се и множество и условия

  3. Използвайте избран резултат и го сравнете

  4. Mysql индексът за дата и време не работи, докато използвате „харесвам“

  5. Използване на BLOB в клауза where в MySQL