WordPress の現場で「サブクエリ」や「二次クエリ」といったとき、多くは メインクエリに対して、テンプレートの途中でもう一本 WP_Query(や同種のAPI)で投稿を取り直している 状況を指します。本稿はその文脈に絞ります。
なお、データベースの SQL でいう「サブクエリ」(入れ子の SELECT など) という説明の仕方もありますし、WP_Query が組み立てる SQL の内部がどうなっているか、という話も別途あり得ます。今回はそちらには踏み込みません。 テーマ側の「二本目のクエリ」と、WP_Query をクラス・インスタンス・メソッドとして理解する話だけを整理します。
テンプレート上の「サブクエリ」(二次クエリ)
一覧や固定ページの表示の途中で、メインとは別の条件で投稿を取り直す処理のことです。関連記事、サイドバーの新着、同カテゴリの抜粋などが典型例です。
実装では WP_Query をもう一度使う、または get_posts() などが内部で同様の仕組みを使う 形が多くなります。
運用上の注意として、グローバルな投稿コンテキスト($post など)に影響するため、wp_reset_postdata() と wp_reset_query() の役割を混同しないことが重要です。また、同じ画面で何度も重ねるとクエリ回数と負荷が増えます。
クラス → インスタンス → メソッド(本稿の焦点)
PHP のオブジェクト指向では、ざっくり次の順で捉えるとわかりやすいです。
- クラス … 「設計図」のようなもの。どんなデータ(プロパティ)を持ち、どんな操作(メソッド)できるかがまとまっている。
- インスタンス … そのクラス(設計図)に基づいて
newで作ったオブジェクト(実体)。同じクラスから、条件を変えて何個も作れる。
メソッド は、クラス内で定義される関数です。インスタンスに対して $instance->メソッド名() のように呼び出し、そのオブジェクトの状態を読んだり進めたりします。
サブクエリ(二次クエリ)で使う WP_Query も、この流れに乗るクラスのひとつです。クラス本体は WordPress コアが定義しており、テーマやプラグイン側では WP_Query をもとに new WP_Query($args) としてインスタンスを作る ことが多いです(メインループ用と、追加の一覧用で 別インスタンス になるイメージ)。
インスタンスを作るコード例
条件配列 $args を渡してインスタンスを生成し、have_posts / the_post など メソッド でループする例です。メインループと併用する場合は、最後に wp_reset_postdata() でグローバルな投稿データを元に戻します。
$args = [
'post_type' => 'post',
'posts_per_page' => 3,
];
$sub_query = new WP_Query($args);
if ($sub_query->have_posts()) {
while ($sub_query->have_posts()) {
$sub_query->the_post();
// ループ内: get_the_ID()、the_title() など既存テンプレートと同様に利用可能
}
wp_reset_postdata();
}
get_posts() のように 関数だけ を呼ぶ API でも、内部では同系統の WP_Query が動いている、という関係があります。
二つの「説明」は両立する
次の二つは矛盾しません。同じ WP_Query を、切り口が違う二通りで説明しているだけです。
-
WordPress のリクエスト構造の話
メインクエリに対して、別条件のクエリ(通称サブクエリ/二次クエリ)を足している。 -
PHP のオブジェクト指向の話
WP_Queryはクラスであり、newでインスタンスを作り、メソッドで操作する。
教える順序としては、テーマ制作の文脈なら (1) → (2)、OOP 入門の文脈なら (2) → (1) でもよいでしょう。
まとめ
- クラス(設計図)→
newでインスタンス(実体)→ インスタンスに対するメソッド呼び出し の流れで読むと、サブクエリ用のWP_Queryも説明しやすい。 - 本稿では メインに対する二本目の一覧取得(テンプレート上の二次クエリ)と、
new WP_Query($args)による実装イメージに限定した。 - SQL のサブクエリや、生成SQLの内部 は別の文脈なので、ここでは扱わない。
WP_Query の細部は、利用している WordPress の版と WP_Query リファレンス などで確認するのが確実です。