2011-01-25 8 views
1

PhpMyAdmin/MySQL Workbenchで動作するようになったMySQLクエリがあります。 入れ子にする方法CodeIgniterのdatamapperのwhere_in節で選択しますか?

SELECT * 
FROM (`medfacts`)  
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`  
where title in ( 
select medfacts.title from medfacts  
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`  
where categories_medfacts.category_id = 2  
)  
or title in ( 
select medfacts.title from medfacts  
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`  
where categories_medfacts.category_id = 3  
) 

は、(クエリが与えられたカテゴリIDと結合テーブルのcategories_medfactsに記載されているすべてのmedfactsを取得します。)私は今まで私のプログラムを可能にする方法で、私のCodeIgniterのプロジェクトにそれを転送する必要が

必要に応じてHaving節を追加します。私が今までにほとんどの場合、クエリを生成しています。

function list_by_category($cat, $module) { 
    /* Get a list of the Medfacts entries that have this category.   * 
    */ 
    $this->db->join('categories_medfacts', 'categories_medfacts.medfact_id = medfacts.id'); 
    $this->where('medfacts.module_id', $module); 
    /* If the category is an array, just get the articles that fall under all categories. 
    * This shouldn't be more than a handful deep. 
    */ 
    if (is_array($cat)) { 
     foreach ($cat as $field => $value) { 
      $this->where_in('title', "select medfacts.title from medfacts JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id` where categories_medfacts.category_id = {$value}"); 
     } 
    } else { 
     $this->where('categories_medfacts.category_id', $cat); 
    } 
    $this->select('medfacts.title'); 
    return $this->get(); 
} 

しかし、私はそれがネストされたSELECT文を逃れられないために取得し、これで終わることができません。

SELECT `medfacts`.`title` 
FROM (`medfacts`) 
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id` 
WHERE ( 
`medfacts`.`module_id` = '2' 
AND `medfacts`.`title` IN ('select medfacts.title from medfacts JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id` where categories_medfacts.category_id = 2') 
AND `medfacts`.`title` IN ('select medfacts.title from medfacts JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id` where categories_medfacts.category_id = 3') 
) 
AND `medfacts`.`site_id` = 1 

お知らせ句のどこでネストされたSELECTの周りに引用符。

Datamapperがネストされた選択をエスケープしないようにする方法はありますか?または、同じ目標を達成するためのよりよい方法がありますか?あるいは私は自分自身でクエリを書くつもりですか?

私は、PHP5のサーバーでCI 1.7.2とDatamapper DMZ 1.7.1を使用しています(現在は問題ありません)。

編集:私はシンプルなor whereがそれぞれwhereケースに一致する記事を返すだろうと認識しています。しかし、それは私が必要なものではありません。私はすべてのカテゴリに該当する結果しか必要としません。私の現在の設定では、or whereが返す結果が多すぎます(リストされたカテゴリに該当するものも含みます)。and whereは何も返しません。また、category_idは "2"と"3")。

また、私は以下のようなJOINもMySQLで動作していますが、上記のがよりクリーンな方法だと思ったので、私はそれをCIに変換できません。

SELECT *  
FROM (`medfacts`)  
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`  
join ( 
    select medfacts.title, medfacts.id from medfacts  
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`  
    where categories_medfacts.category_id = 2  
) m1  
on m1.id = medfacts.id  
join ( 
    select medfacts.title, medfacts.id from medfacts  
JOIN `categories_medfacts` ON `categories_medfacts`.`medfact_id` = `medfacts`.`id`  
    where categories_medfacts.category_id = 3  
) m2  
on m2.id = medfacts.id  
where `medfacts`.`module_id` = '2'  
and medfacts.site_id = 1 
+0

WOW!私は質問を読んだことはありませんが、あなたは複数のサブクエリを行い、複数のカテゴリID 'categories_medfacts.category_id'にマッチするように結合していますか?私はそのクエリを最適化する方法を尋ねることをお勧めします! – ifaour

+0

おそらくあなたはその質問を読むべきでしょうか?私は、同じ結果を達成するより良い方法があるかどうか尋ねました。 – Shauna

+0

このクエリが返すものは次のとおりです: 'SELECT * FROM medfacts、categories_medfacts WHERE categories_medfacts.medfact_id = medfacts.id AND categories_medfacts.category_id IN(2,3)' – ifaour

答えて

2

私はCIで副選択を実行することが分かっ唯一の方法があります - http://heybigname.com/2009/09/18/using-code-igniters-active-record-class-to-create-subqueries/

は、いくつかの時間前、私は非常に熟練したプログラマ(実際に私のボス:D)で警告されている、しかし、副問い合わせが非常にあること遅く、複数の別々の選択を実行するか、代わりに(可能であれば)参加をしようとするのがはるかに高速です...ベンチマークする機会がなかったので、マイナーな提案としてください:)

+0

私は必要に応じて全く違う方法で問題を抱えていませんが、より良い方法で。最初のクエリでは、どこで...の代わりに使用された結合が出てきましたが、CI/DMZはまだ私が試したことを気に入らなかった。あなたのリンクの助けを借りてもう一度お試しになります(ありがとうございます)。 – Shauna

+0

あなたのリンクで提供されているメソッドがそのリンクに書かれているように機能しませんでした(私のサブクエリは複数の値を返します)ので、JOINでそのクエリを作成するメソッドを使用しようとしました。リンク内のメソッドを使用してサブクエリを作成し、JOINを介して追加すると、必要な結果が得られます(これは私の質問に追加したSQLを生成します)。私はそれがいかに効率的かは分かりません。 – Shauna

+0

MySQL EXPLAINを試して、クエリの実行方法を確認してください。インデックスが正しく設定されていて、選択時間が間違っている場合は、これをさらに最適化する必要はありません。http://dev.mysql.com/doc/refman/5.0/en /explain.html –

関連する問題