「WordPressで学ぶPHP(4)通信編」を発売しました。
本書は、「WordPressで学ぶPHP(1)変数・制御構造編」「WordPressで学ぶPHP(2)データ構造編」「WordPressで学ぶPHP(3)関数編」の続編にあたり、Webブラウザとサーバー(PHP)との通信と、PHPから他のサーバーに通信することについて解説します。
MT5のPHP APIを探る(その4)
「MT5のPHP APIを探る」の第4回をお送りします。
今回は、複数のテーブルを結合する方法を紹介します。
1.複数のテーブルの結合
一連の記事の「その2」に、結合の条件を指定する方法を書きました。
複数のテーブルを結合する場合、その書き方を拡張して、結合方法を表す配列を複数回書きます。
例えば、IDが2番のブログから、「お知らせ」というカテゴリに属するブログ記事(かつ公開されている記事)を、日付の新しい順に読み込みたいとします。
この場合、以下の2つの条件で結合を行い、かつカテゴリ名(category_labelフィールド)の値が「お知らせ」という条件を指定します。
- mt_entryテーブルのentry_idフィールドと、mt_placementテーブルのplacement_entry_idフィールドが等しい
- mt_placementテーブルのplacement_category_idフィールドと、mt_categoryテーブルのcategory_idフィールドが等しい
結合と検索条件を指定する部分のプログラムを書くと、以下のようになります。
$extras['join'] = array( 'mt_placement' => array( 'condition' => 'placement_entry_id = entry_id' ), 'mt_category' => array( 'condition' => 'placement_category_id = category_id' ) ); $where = <<< HERE entry_blog_id = 2 and entry_status = 2 and category_label = 'お知らせ' order by entry_authored_on desc HERE; require_once('lib/class.mt_entry.php'); $_entry = new Entry; $entries = $_entry->Find($where, false, false, $extras);
2~4行目と、5~7行目で、前述の2つの結合条件を順に指定しています。
そして、12行目でカテゴリ名(category_labelフィールド)の値が「お知らせ」という条件を指定しています。
2.同じテーブルを複数回結合する
場合によっては、同じテーブルを2回以上結合し、それぞれで別々の検索条件を指定したいこともあります。
SQLでこのようなことを行うには、それぞれのテーブルに別名を付けて区別します。
MT5のPHP APIでも、テーブルに別名を付けることができます。
その場合、連想配列で結合条件を指定する際に、テーブル名の後に別名を書きます。
また、一般のSQLと同様に、フィールドを「テーブルの別名.フィールド名」のように指定します。
例えば、以下のような例を考えてみます。
- IDが2番のブログから、公開されているブログ記事を読み込みます。
- ベースネームが「price」という整数型のカスタムフィールドの値が、1000以上2000以下になっているという条件を指定します。
- ベースネームが「weight」という整数型のカスタムフィールドの値が、500以上1000以下になっているという条件を指定します。
- priceカスタムフィールドの昇順でブログ記事を並べ替えます。
- priceカスタムフィールドの値が同じブログ記事が複数ある場合は、それらをweightカスタムフィールドの項順で並べ替えます。
この場合、カスタムフィールドの情報があるテーブル(mt_entry_meta)を2回結合し、それぞれでprice/weightカスタムフィールドの結合/検索条件を指定します。
結合と検索条件を指定する部分のプログラムを書くと、以下のようになります。
$extras['join'] = array( 'mt_entry_meta m1' => array( 'condition' => 'm1.entry_meta_entry_id = entry_id' ), 'mt_entry_meta m2' => array( 'condition' => 'm2.entry_meta_entry_id = entry_id' ) ); $where = <<< HERE entry_blog_id = 2 and entry_status = 2 and m1.entry_meta_type = 'field.price' and m1.entry_meta_vinteger_idx between 1000 and 2000 and m2.entry_meta_type = 'field.weight' and m2.entry_meta_vinteger_idx between 500 and 1000 order by m1.entry_meta_vinteger_idx, m2.entry_meta_vinteger_idx desc HERE; require_once('lib/class.mt_entry.php'); $_entry = new Entry; $entries = $_entry->Find($where, false, false, $extras);
まず、2~4行目と5~7行目で、ブログ記事のテーブルにカスタムフィールドのテーブルを2回結合しています。
テーブル名を指定する部分を「mt_entry_meta m1」「mt_entry_meta m2」と書いていて、それぞれに「m1」「m2」の別名を指定しています。
12~13行目では、priceカスタムフィールドの値が1000以上2000以下という条件を指定しています。
1回目の結合でテーブルにm1という別名を付けましたので、条件の中でフィールドを指定する箇所を「mt.entry_meta_type」のように書いて、別名を指定しています。
14~15行目では、12~13行目と同じ考え方で、weightカスタムフィールドの値が500以上1000以下という条件を指定しています。
そして、16行目で並べ替えの条件を指定しています。
ここでも、フィールド名の前に「m1.」「m2.」の別名を指定します。