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

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

新規登録して質問してみよう
ただいま回答率
85.51%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

1回答

571閲覧

$wpdbを使い【指定タームを持つ記事を対象にする場合】について教えて下さい。

daijin

総合スコア17

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

WordPress

WordPressは、PHPで開発されているオープンソースのブログソフトウェアです。データベース管理システムにはMySQLを用いています。フリーのブログソフトウェアの中では最も人気が高く、PHPとHTMLを使って簡単にテンプレートをカスタマイズすることができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/12/06 21:10

編集2022/01/12 10:55

前提・実現したいこと

お世話になります。WordPressの$wpdbについての質問になります。宜しくお願い致します。

記事に紐づくユーザー情報「count」がありまして、それを$wpdbを介して取得し、ランキングを表示しております。

それはできたのですが、取得対象の記事を指定タームの記事にしたい。というところで現在、悪戦苦闘しております。

発生している問題

次に示す該当のソースコード【1】において、
WHERE = ( $targets )
によってIDが58のタームを持つ記事を対象にしたいがこれができない。

尚該当のソースコード【2】で全ての記事を対象とするものはできている。

該当のソースコード【1】

PHP

1// 【1】指定ターム(58)を対象にするこのコードが機能しない 2function CountRanking_tarm ( $tarmId ){ 3 $tarmId = '58'; 4 global $wpdb; 5 // IDが58のタームを持つnewsの記事を対象とする 6 $targets = $wpdb->get_results( " 7 SELECT tr.object_id 8 FROM $wpdb->term_relationships AS tr INNER 9 JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id 10 WHERE post_type = 'news' 11 WHERE tt.term_id = $tarmId 12 " ); 13 // 対象の記事から「count」の数のランキングを作る 14 $counts = $wpdb->get_results( " 15 SELECT p.post_author AS user_id, sum(m.meta_value) AS SumUser 16 FROM $wpdb->posts AS p, $wpdb->postmeta AS m 17 WHERE = ( $targets ) 18 AND p.post_status = 'publish' 19 AND m.meta_key = 'count' 20 GROUP BY p.post_author 21 ORDER BY m.meta_value DESC LIMIT 10 22 " ); 23 // ランキングを出力する 24 $result = ''; 25 foreach ( $counts as $count ) { 26 $result .= '<ul>' 27 $result .= '<li>'.get_avatar($count->user_id, 95).'</li>'; 28 $result .= '</ul>' 29 } 30 return $result; 31}

###該当のソースコード【2】

PHP

1// 【2】全ての記事を対象にするこのコードは機能する 2function CountRanking_all (){ 3 global $wpdb; 4 // 全ての記事から「count」の数のランキングを作る 5 $counts = $wpdb->get_results( " 6 SELECT p.post_author AS user_id, sum(m.meta_value) AS SumUser 7 FROM $wpdb->posts AS p, $wpdb->postmeta AS m 8 WHERE p.ID = m.post_ID 9 AND p.post_status = 'publish' 10 AND m.meta_key = 'count' 11 GROUP BY p.post_author 12 ORDER BY m.meta_value DESC LIMIT 10 13 " ); 14 // ランキングを出力する 15 $result = ''; 16 foreach ( $counts as $count ) { 17 $result .= '<ul>' 18 $result .= '<li>'.get_avatar($count->user_id, 95).'</li>'; 19 $result .= '</ul>' 20 } 21 return $result; 22}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

いろいろ想像で補って SQL を修正。

動いていると書かれている ソースコード【2】の SQL 部分 $counts = $wpdb->get_results("〜") を利用して書いてます。 $tarmId を引数で渡したいとかは、工夫してみてください。

とりあえず、テストしていませんが、こんな感じで、記載すれば動くのではないでしょうか。
ソースコード【2】 の内容と同じ感じで、 news の ターム 58 の投稿者と count の合計が得られるはずです。

外部から 引数を与える場合は、不正な文字を処理しないために prepare を利用した方が良いので、利用しています。

PHP

1() 2 $tarmId = 58; 3 $counts = $wpdb->get_results( $wpdb->prepare( " 4 SELECT p.post_author AS user_id, sum(m.meta_value) AS SumUser 5 FROM $wpdb->posts AS p, $wpdb->postmeta AS m 6 WHERE p.ID = m.post_ID 7 AND p.ID IN ( SELECT tr.object_id 8 FROM $wpdb->term_relationships AS tr, $wpdb->posts AS p, $wpdb->term_taxonomy AS tt 9 WHERE p.post_type = 'news' 10 AND tt.term_id = %s 11 and p.id = tr.object_id 12 AND tr.term_taxonomy_id = tt.term_taxonomy_id 13 ) 14 AND p.post_status = 'publish' 15 AND m.meta_key = 'count' 16 GROUP BY p.post_author 17 ORDER BY m.meta_value DESC LIMIT 10 18 ", $tarmId ) ); 19()

参考: https://wpdocs.osdn.jp/関数リファレンス/wpdb_Class

なお、$wpdb を使うのであれば、SQL について最低限の理解は必要ですので、SQL も学習するようにしましょう。

投稿2018/12/06 22:27

編集2018/12/07 03:04
CHERRY

総合スコア25164

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

daijin

2018/12/06 23:04

CHERRY様、おはようございます。的確なご指摘に感謝致します。まだ出来ないようでしたので、他にも何かあればまた宜しくお願い致します。
CHERRY

2018/12/06 23:13

WordPress を介さずに mysql クライアントで SQL を直接実行したら値は取得できるのでしょうか?
daijin

2018/12/06 23:17

$wpdbでやる方法だけ、検索したものの詰め合わせで書いたので、MySQLから直接という方法は分からないです。ごめんなさい。お気遣いありがとうございます。
CHERRY

2018/12/07 00:46 編集

SQL が間違っていたら、実行しても結果が 0 件になるので、SQL を直接 MYSQL で実行したら該当する記事が表示されるのか確認したかったのですが...  なんとか実行することはできませんか? phpMyAdmin 経由でも実行できると思うのですが...
CHERRY

2018/12/07 00:50 編集

出先なので、確認できていないのですが、 `$targets` に代入している SQL で、 post_type が入っているのが気になるんですよね。 あれ? ` WHERE = ( $targets ) ` もおかしいな。 本格的に SQL 文を見直さないとダメだなぁ...
CHERRY

2018/12/07 00:59

やりたいことの再確認ですが、 カスタム投稿タイプ `news` の中で ターム id `58` を指定した記事の投稿者別に カスタムフィールド `count` の数字を集計して、多い順に 10 件表示したい ということでよろしいですか?
CHERRY

2018/12/07 03:06 編集

昼の待ち時間に 想像で補って、回答を修正しました。試してみていただけますか?
daijin

2018/12/07 06:44 編集

ありがとうございます。ご返信が大変遅くなってしまい申し訳ございませんでした。まとめてお答え致します。 >SQL が間違っていたら、実行しても結果が 0 件になるので、 これはよくわからないのですが、【2】は同じテンプレートに書けば動くので大丈夫では、と考えるレベルです。 >`$targets` に代入している SQL で、 post_type が入っているのが気になる >` WHERE = ( $targets ) ` もおかしい 似た要件のソーコードを探してコピペしてしまいました…。 >やりたいことの再確認ですが、 その通りです。
daijin

2018/12/07 06:45

>試してみていただけますか? 感激です。せっかくのお昼休みを割いて頂きありがとうございます。 試しましたご報告です。 <div> <?php echo CountRanking_tarm(); ?> </div> ↓ ・特に何もなく「<div></div>」の出力でした。 ・ほかに問題は起きてないので、間違いは文法や誤字でなく取得にあるようです。 ・AND p.ID IN ()の部分を削除すると、全ての記事を対象にしたランキングが出力されます。 自分でももう少しいろいろ調べて、使えるコピペがないか探してみます。笑 最後に、参考リンクの関数リファレンありがとうございます。拝見してみマシたが「posts AS p」や「tt」とかリファレンスに載ってなかったりして厄介ですね…
CHERRY

2018/12/07 07:14

> foreach ( $counts as $count ) { > $result .= '<ul>' > $result .= '<li>'.get_avatar($count->user_id, 95).'</li>'; > $result .= '</ul>' > } の部分で、 ` ; ` が抜けている行が2行ありますが、 ここでエラーになっていたりしないでしょうか?
daijin

2018/12/07 07:19 編集

なるほど、SQLはwordpressとは全く別の機能なのでリファレンスにないんですね。 セミコロン抜けはここに書く際のタイプミスで実際は大丈夫でした。ありがとうございます。
daijin

2018/12/07 08:19

DBOnlineさんわかりやすいですね!ありがとうございます。 あと今回のターム58なんですが、これは元からあるタグでなく独自に作ったタームですが、その点でできなくなることはありませんよね?
daijin

2018/12/07 15:27 編集

こんばんは。ご提示頂いたソースコードで出来ない原因が分かったかもしれません。 集計したいのは 「指定タームに属す投稿、のcount」ではなくて、 「指定タームに属す投稿、にされたコメント、のcount」です。 つまり、コメントについているデータが「count」で、コメントの投稿タイプが「news」です。
daijin

2018/12/07 12:27 編集

以上のことを踏まえてみると、 AND p.ID IN ( ) の中で WHERE p.post_type = 'news' のように投稿タイプを指定するのは良さそうですが、 AND tt.term_id = %s のようにタームを指定するのは間違ってそうです。 なぜならターム58は、「コメント(投稿タイプnews)」ではなくて、その親の記事が持っているタームだからです。 図にしますとこうです。 記事 → これがターム58 | |- Aさんのコメント(news)→ ここにcountがついてる | |- Bさんのコメント(news)→ ここにcountがついてる | このようにターム58の記事にされたコメントについているデータが「count」なので、 AND tt.term_id = %s のようにタームを指定するのは AND p.ID IN ( ) の中ではなく外に置いた方が良いのかな?と思ったのですが、、
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問