WordPressのカスタムクエリを使ってテーブルを結合させたり、取得するデータを追加する方法

ところで、WordPressのカテゴリーのアーカイブページでは、カテゴリーに所属する投稿の一覧が表示されますね。

この表示する内容をもっと拡張したい。投稿に紐づけて別のテーブルのデータを利用して、もっといろいろ情報を表示させたいな~と思いました。

どうやら「カスタムクエリ」を使うとできそうです。

カスタムクエリを使ってテーブルを結合する

例として、下のようにWordPressの投稿に関するデータが入っている「wp_posts」テーブルと、独自で作った「location」テーブルの2つのテーブルがあるとします。

「wp_posts」テーブル

ID post_author post_title
1918 1 味の素スタジアム
1922 2 豊田スタジアム
1940 3 札幌ドーム

「location」テーブル

ID pref
1918 tokyo
1922 aichi
1940 hokkaido

上の2つのテーブルそれぞれには他にもフィールド(カラム、列と呼ぶこともある)があるんですが、一部抜粋して簡略化しています。

この2つのテーブルを「ID」で紐づけて結合すれば、やりたいことができそうだな~というイメージです。

2つのテーブルをIDで紐づけて結合するイメージ

ID post_author post_title pref
1918 1 味の素スタジアム tokyo
1922 2 豊田スタジアム aichi
1940 3 札幌ドーム hokkaido

というわけで、上の2つのテーブル「wp_posts」「location」が作成されていると仮定して、下のコードをfunctions.phpファイルに追記します。

//テーブルを結合
add_filter('posts_join', 'table_join');
function table_join($join){
 global $wpdb;
 if ( is_category() ) {
  $join .= " INNER JOIN location ON $wpdb->posts.ID = location.ID ";
 }
 return $join;
}

コードがやっていること

カテゴリーのアーカイブページを表示している場合は、「posts_join」のフックを使って$wp_queryで発行されるSQL文に「location」テーブルを内部結合して、「wp_postsテーブルのID」と「locationテーブルのID」が同じものだけ表示させるように条件を付けたものを追加しています。

カスタムクエリを使ってデータ取得したいフィールドを追加する

次に、結合したテーブルからデータ取得をします。

下のコードをfunctions.phpファイルに追記します。

//取得したいデータのフィールドを追加
add_filter('posts_fields', 'add_fields');
function add_fields( $fields ) {
 if ( is_category() ) {
  $fields .= ',location.pref';
 }
 return $fields;
}

コードがやっていること

「posts_fields」のフックを使って$wp_queryで発行されるSQL文に「location.pref」のデータを取得するように追加しています。

2つのカスタムクエリを使って発行されるSQL文を見てみよう

ここまでで行ったカスタムクエリを使うとどのようなSQL文が発行されるのか、見てみましょう。例えば、アーカイブページを表示するテンプレート「archive.php」ファイルに以下のコードを追記します。

<?php echo $wp_query->request; ?>

すると、下のようなSQL文が発行されていることがわかります。太字の部分がカスタムクエリで追加した部分ですね。

SELECT SQL_CALC_FOUND_ROWS wp_posts.*,location.pref FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN location ON wp_posts.ID = location.ID WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (1) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 10

カスタムクエリを使って取得したデータを表示するには

カスタムクエリでテーブルを結合、データを取得したものを表示させたいとします。もう一度、結合したテーブルのイメージを見ましょう。

ID post_author post_title pref
1918 1 味の素スタジアム tokyo
1922 2 豊田スタジアム aichi
1940 3 札幌ドーム hokkaido

「pref」フィールドのデータを取得するには、下のようにループ内にコードを書けばOKです。

<?php
if ( have_posts() ) : while ( have_posts() ) : the_post();
 echo $post->pref; //prefのデータを表示
endwhile; endif;
?>

カスタムクエリは便利

使い方を工夫すれば、特定のページのURLに対して「クエリパラメーターが設定されている値でソートや除外」とかもできるので、やれることが広がって便利だなぁと思います。

今回はカテゴリーのアーカイブページを例にしましたが、「カスタムクエリ」のページでは他にもいろいろなサンプルコードと解説が書かれています。勉強になるなぁ~。

著者:bouya Imamura