sql >> データベース >  >> RDS >> Mysql

同じクエリで投稿とタグをクエリする

    group_concat 文字長が原因で信頼性が低いため、連結するデフォルトの制限は1024文字ですが、手動 ただし、定義された制限に完全に依存することはできません。代わりに、データをフェッチしているようにアプリケーションレイヤー(php)で処理でき、投稿とその関連タグを表示したい場所で、各投稿の投稿ごとに結合クエリを使用できます。複数のタグを含めることができるため、各投稿行に1つのタグがあり、同じ投稿の別の行に2番目のタグがあるため、結果セットには重複する投稿データが含まれます。結果をループすると、各投稿が1回だけ表示されます。チェックを追加する

    $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 ループ内の前の投稿IDが同じ投稿であるかどうかを確認し、条件が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>...
    

    データを表示しておらず、他の場所(Webサービス)で使用している場合でも、1つの結合クエリを使用し、配列/オブジェクトを作成してデータを変換します。各投稿には、以下のような関連タグの配列があります

    $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で 結果として連結されたタグが順序付けられ、2番目の列に同じ順序付け基準を設定できるようにします

    $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. PostgreSQLでINSERTまたはUPDATEの影響を受けるレコードの数を取得します

    2. postgres 9.2でコピーを実行した後、値の前後に一重引用符が表示されます

    3. 私のリソースを浪費する奇妙なSQL

    4. SQLですべての組み合わせを生成する