WordPressで特定のカテゴリの件数をSQLで取得し表示する

WordPressでの改造ネタです。

Webサービス集めましたというサイトにて取得している投稿記事数表示について再考したところ、カテゴリ名のカウントで一発で持ってこれることに気づきました。

WordPressで特定のカテゴリ記事の数を表示したい、取得したいという人向けの記事になります。

スポンサーリンク

以前のおさらい

以前、書いた記事でWordPressで投稿記事数をカウントする方法+特定の記事を除外する工夫とありました。これは勉強不足ということで何が駄目かというと、全記事数取得はいいのですが、月間ランキング記事のように特定記事を除外という発想がまずいということです。

除外ということは、さらに記事が別途増えればそれらを除外することになり、メンテナンスも大変です。

当時なぜ除外としたかというと、wp_postsという投稿テーブルの件数を取ってくるくらいしか頭が働かなかったのと、そもそもカテゴリ名情報がwp_postsにないよね?ということで終わっていたというのがあります。

カテゴリ単位で記事数を取得する

それらを踏まえて改造したコードはこちらになります。

このコードはSQLが特徴的で、そのSQLを理解するには、Wordpressのデータベース構造を理解する必要があります。

WordPressのデータベースのテーブルってどうなってるの?という記事が分かりやすかったです。WordPressCode日本語版のデータベース構造は図になってるので理解し易いです。

SQL文だけ取り出すと、

SELECT count FROM wpwa_term_taxonomy
WHERE taxonomy = ‘category’
AND term_id =
(SELECT term_id FROM wpwa_terms WHERE slug  = ‘webservice’)

となっています。

wpwaはWordpressのデータベース名につく接頭辞というものです。識別しやすいようにつけられるものですかね。

やっているのは、

1.termsテーブルからterm_idを取得する。条件はslugがwebserviceのもの(ここでは、Webサービスのカテゴリ記事が欲しい)

2.term_taxonomyテーブルから、1で取ってきたterm_idと一致して、かつtaxonomyがcategoryというもの件数を取得する(count項目を取得)

という二段階となっています。

taxonomyがカテゴリといってるのは、例えばタグなどもここで管理されているため、念のためというところです。slugとはWordpress管理者側が任意でつけるためつけてないと日本語とかになってるかもしれません。ちなみに管理画面は、カテゴリのところで設定できます。

たまたまここではwebサービスカテゴリのterm_idは4でした。これは環境によって異なるし、例えばカテゴリを追加したり、つけなおしたりすると変更されるためこのような作りが最適なのかなと思います。例えばterm_idが9とかになっても「slugがwebservice」であれば取れるということですね。

term_taxonomyテーブルにはカテゴリ毎の記事数が入っているのでそれを取ってくるだけでオッケーとなります。これもWordpress管理画面のカテゴリ画面で「カウント」と表示されているものが該当する感じですね。

以前の知識だと、wp_postsにないからどう取ってくるのかわからなかったのですが、wp_postsにあるidとterm_relationshipsテーブルのidがひも付き、さらにそこからtaxonomy_idとterm_taxonomyテーブルのtaxonomy_idとひも付き、、みたいなのが上の図のテーブル図となっていますね。

以上が説明となります。

これで、カテゴリ毎の記事数取得も容易になり、コードも分かりやすくなったかなと思います。全記事数から引き算するとかも不要ですし、こっちのほうがいいかなというところです。

補足や修正

MySQLをphpAdminなんかで使う時に、以前はテーブルの項目名は「`」(グレイブ・アクセント)が必須だと思ったのですが、とくに必要がなさそうです。phpAdminのSQL実行環境でいるだけなのか、とくになしでも問題ないので、スッキリしたほうにしてみました。

termsテーブルのSELECT分はサブクエリと言ったりしますが、実はこれはややまずいかなと思います。というのは、slug自体が仮に同じ「Webservice」をつけてしまえば複数該当することになり、SQLでエラーが起きそうということです。Wordpress管理画面で既存のスラッグをつけようとすると「注意」されるのと、あとつけても「webservice-2」のような配慮は動きとしては確認できました。たださらに、like演算子で%like%のようにしていないため「webservice-2」は取得しませんでした。といいつつ、そもそもlikeにしている意味はなく、SQLも遅くなるであろうと考えられるため、等号にするのが良さそうです(既に変更済み)。上のコードも直しておきました。

このサブクエリで複数レコードがあると、inなどで処理をしないとterm_idと一致する条件として認識出来ないため、複数ありえるならMAXなど集合関数をかます必要があるかなと思います。今回はslugがwebserviceでまず問題は起きないわけですが。このあたりも勉強していくと面白いところですね。

おわりに

WordPressのデータベース構造は知らなくてもいいわけですが、知っているとこういった件数表示などの処理も出来るし面白いですよね。

これで、Webサービスカテゴリの記事件数を表示することが出来、今後別カテゴリで新規記事を作ってもそれは除外されるためいい感じで運用できそうです。

ビジネスって面白い、アイデアの価値ってもっとある。そんなことを自分なりに伝えられないかという思いから、シゴトクリエイターをやっています。一緒に楽しいビジネスを生みだしていきましょう。1記事でも何かヒントになれば嬉しいです。

スポンサーリンク