質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.99%

WordPressで、「WP_Query」を「オリジナルのSQL」へと書き換えたい

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 607

jaimy

score 7

実現したいこと

「WP_Query」を「オリジナルのSQL」へと書き換えたいです。

具体的にいいますと、こちらの「$event_query」に、後の「オリジナルのSQL」を入れたいです。

if($event_query->have_posts()): while($event_query->have_posts()): $event_query->the_post();
  the_title();
endwhile; endif;

オリジナルのSQL

カスタムフィールド「cf_number」に応じて記事を取得するオリジナルのSQLがこちらで、問題ないです。

function my_posts_join( $join ){
  global $wpdb;

  if( ! is_admin() ) {
    $join .= "INNER JOIN ". $wpdb->postmeta ." ON ". $wpdb->posts .".ID = ". $wpdb->postmeta .".post_id ";

    $join .= "INNER JOIN ( ";
    $join .= "  SELECT ". $wpdb->postmeta .".meta_value as cf_number, max(". $wpdb->posts .".post_date) as max_date ";
    $join .= "      FROM  ". $wpdb->posts;
    $join .= "      INNER JOIN ". $wpdb->postmeta ." ON ". $wpdb->posts .".id = ". $wpdb->postmeta .".post_id  ";
    $join .= "      WHERE ". $wpdb->postmeta .".meta_key = 'cf_number' ";
    $join .= "      GROUP BY ". $wpdb->postmeta .".meta_value ";
    $join .= "    ) AS j1 ";
    $join .= "  ON ". $wpdb->postmeta .".meta_value = j1.cf_number AND ". $wpdb->posts .".post_date = j1.max_date ";
  }

  return $join;
}

add_filter('posts_join', 'my_posts_join' );

試したこと

上の「オリジナルのSQL」を「$event_query」に入れるために、「posts_request」を使ってみました。しかし下記の書き方ではできませんでした。

間違っているところがどこか、分かりますでしょうか?

<?php
// 「オリジナルのSQL」に書き変える
add_filter('posts_request', function ($query) {
  global $wpdb;
  $query = "
    SELECT wp_posts.ID
    FROM wp_posts
    INNER JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id
    INNER JOIN ( 
        SELECT wp_postmeta.meta_value as cf_number, max(wp_posts.post_date) as max_date
        FROM   wp_posts
        INNER JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id 
        WHERE wp_postmeta.meta_key = 'cf_number'
        GROUP BY wp_postmeta.meta_value
      ) AS j2
      ON wp_postmeta.meta_value =j2.cf_number AND wp_posts.post_date = j2.max_date
  ";
  return $query;
});

// 「オリジナルのSQL」で記事を取得する
$event_query = new WP_Query([
  'posts_per_page' => 20,
]);
if($event_query->have_posts()): while($event_query->have_posts()): $event_query->the_post();
  the_title();
endwhile; endif;
?>

追記

なぜ「my_posts_join」だけでメインループを使うという方法ではなくて、わざわざ「$event_query」を使うのか。といいますと、記事を「表示ボタン」をクリックしたときに指定のdiv内に表示したいためです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正の依頼

  • KazuhiroHatano

    2019/04/25 01:34

    何がどうダメだったのか、お願いします
    少なくともまるっとSQLを上書きしちゃってるから
    posts_per_pageが効かなくなってるだろうし
    フィルタに条件がないので後のget_postsとかに影響してしまうだろうし
    post_statusの条件がないのでゴミ箱の中のものも拾うだろうし
    $wpdb->postsとかでテーブルの名前を取得していないので
    プレフィクスがwp_じゃなかったら動かないだろうし
    たくさん問題は見えます

    キャンセル

  • dany

    2019/07/14 18:50 編集

    そこまでオリジナルSQLへのこだわりが強ければ、WP_Queryを使うメリットがないのでは?

    <?php

    $event_posts = $wpdb->get_results($wpdb->prepare("SELECT * FROM $wpdb->posts INNER JOI..."));

    $event_posts = array_map('get_post', $event_posts);

    foreach ($event_posts as $p) {
    echo get_the_title($p->ID);
    } ?>

    キャンセル

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.99%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる