web-dev-qa-db-ja.com

複数の値に対するJDatabase JOIN

Xに等しいかnullである変数で2つのテーブルを結合するJOINステートメントのJDatabase構文は何ですか?たとえば、複数の値で結合します。

通常のSQL でこれを実行できることを示すいくつかの例を見つけましたが、それがJDatabase構文にどのように変換されるのかわかりません。

私のクエリは現在、変数(a.animal)がb.idと等しい場合に機能しますが、変数(a.animal)が空の場合にも結合する必要があります。

$query1 = $db->getQuery(true)
    ->select ($db->quoteName(array('a.date','a.reminder','a.type','a.animal','a.mob')))
    ->select ($db->quoteName('b.nameandid') .'AS'. $db->quote('animalname'))    
    ->from ($db->quoteName('app_reminders', 'a'))    
    ->join('INNER', $db->quoteName('app_animal', 'b') . 'ON (' .$db->quoteName('a.animal'). 'LIKE' .$db->quoteName('b.id').')')
    ->where ($db->quoteName('a.date') . '>=' . 'NOW()', 'AND')    
    ->where ($db->quoteName('a.user_id') . 'LIKE' . $db->quote($userid));
3
Hannah Smith

ONステートメントでは、ANDORを組み合わせた複数の条件を追加できるはずです。したがって、このようなことでうまくいくはずです:

->join('INNER', $db->quoteName('app_animal', 'b') . 'ON (' .$db->quoteName('a.animal'). 'LIKE' .$db->quoteName('b.id').' OR ' . $db->quoteName('a.animal') . ' IS NULL)')
3
fruppel

いくつかの懸念事項と改善点がありますが、最初にコードにスキップして、後で説明します。

次のように表示されるクエリを生成したいとします。

_SELECT a.date, a.reminder, a.type, a.animal, a.mob, b.nameandid AS 'animalname'
FROM app_reminders a
LEFT JOIN app_animal b ON a.animal = b.id
WHERE a.date >= NOW() AND a.user_id = 3
_

リンクされたStackOverflowページの質問のJOINJOINが_LEFT JOIN_を使用していることに注意してください。その質問のOPは、すべての結合されたテーブルの値を持つ行のみを必要としています。答えはJOIN(通常の結合、別名_INNER JOIN_)を使用します。これにより、結合値としてnullを含む行が無視されます。

あなたは何か違うものが欲しい。 2番目のテーブルに行に結合する修飾値が含まれているかどうかに関係なく、最初のテーブルの行が必要です。これには、_LEFT JOIN_が必要です。これが SQLFiddle Demo で、結合の結果を試して比較したい場合に使用します。 (これが目的のアクションでない場合は、このリンクを使用して、正しくないものを表現できるはずです。)_LEFT JOIN_を使用すると、チェックするために追加の条件を追加する必要はありません_IS NULL_。

として...

  1. LIKE演算子を使用していますが、_%_または___ワイルドカードを使用していないため、LIKEと記述する理由はありません。 _=_に単純化します。
  2. datetypeはmysql [〜#〜] keywords [〜#〜] ですが、- 予約済みキーワード ではないため、そうではありませんバッククォートで囲む必要はありません。これは、他のすべての列とテーブル名にも当てはまります。これらすべてのエンティティでqn()/quoteName()を使用することはできますが、クエリの構文とコードに膨張を追加するだけです。
  3. クエリをより人間が読めるようにするには、比較演算子の両側に単一のスペースを含めます。 (例:_'LIKE'_は_' LIKE '_より優れています)
  4. セキュリティ上の予防策として、_$userid_変数をクエリに適用する場合は、整数_(int)_としてキャストします。整数値は引用符で囲む必要はありません。
  5. 読みやすさ/コード理解を向上させることを目的とした個人的な好みの問題として、重複するメソッド呼び出しを単一の句の連結手法として使用しないようにしています。私が提案するJoomlaスニペットでは、1つのselect()と1つのwhere()呼び出しのみを使用します。 (複数のテーブルを結合する場合、複数のjoin()呼び出しの存在は論理的/直感的です。)

Joomla構文(引用メソッドは呼び出されません):

_$query = $db->getQuery(true)
            ->select("a.date, a.reminder, a.type, a.animal, a.mob, b.nameandid AS 'animalname'")
            ->from("app_reminders a")
            ->joinLeft("app_animal b ON a.animal = b.id")
            ->where("a.date >= NOW() AND a.user_id = " . (int)$userid);
_

pS実際にLIKEをワイルドカード文字とともに使用したい場合は、 この投稿 が安全な方法を示します-Joomlaドキュメントからのソースです。

1
mickmackusa