【2026年10月20日時点の情報です】
このブログは、自宅のAlmaLinuxサーバーでWordPressを動かしています。2026年10月16日、ブログの記事を整理していて、Laravelの記事25本などを、SQLでまとめて下書きに戻しました。この日に公開をやめた記事は、合わせて47本です。
ところが、記事が1本もなくなったはずのカテゴリー「Laravel」と「募集終了」が、サイドバーのカテゴリーの一覧に残ったままでした。
原因は、SQLで記事の状態を変えても、WordPressがカテゴリーの記事の数を数え直さないことでした。この記事では、そのときに起きたことと、数え直したSQLをまとめます。
場面1:SQLで記事をまとめて下書きに戻した
管理画面で1本ずつ「下書きへ切り替え」を押すと時間がかかるので、記事のIDを並べて、1回のSQLで下書きにしました。その前に、戻せるように25本だけの控えを取っています。
sudo mysqldump wordpress wp_posts --where="ID IN (1235,1239,1259)" > ~/work/wp_posts-backup-20261016-laravel.sql
sudo mysql wordpress -e "UPDATE wp_posts SET post_status = 'draft' WHERE ID IN (1235,1239,1259) AND post_status = 'publish';"実際には、IN のかっこの中に25本のIDを並べました。
- mysqldump wordpress wp_posts –where=”ID IN (…)”:
wp_posts のテーブルから、かっこの中のIDの行だけを控えのファイルに書き出す - UPDATE wp_posts SET post_status = ‘draft’:
記事の状態を、下書き(draft)に変える - WHERE ID IN (…):
かっこの中のIDの記事だけを対象にする - AND post_status = ‘publish’:
公開中のものだけを変える(すでに下書きのものは触らない)
記事は思ったとおり下書きになり、開くと見つからないページになりました。
場面2:記事が0本のカテゴリーが、サイドバーに残った
ところが、サイドバーのカテゴリーの一覧を見ると、「Laravel」と「募集終了」がそのまま出ていました。どちらも、この日に記事をすべて下書きにしたカテゴリーです。
WordPressは、カテゴリーごとの記事の数を、wp_term_taxonomy というテーブルの count という列に入れておいて、それを使っています。サイドバーのカテゴリーの一覧は、この count が0のカテゴリーを出さない設定です。
この count は、管理画面で記事を公開したり下書きにしたりしたときに、WordPressが数え直して書き換えます。SQLで wp_posts を直接書き換えたときは、その数え直しが動きません。そのため、count が下書きにする前の数のまま残り、カテゴリーが「記事がある」と扱われていました。
| No. | 項目 | 管理画面で下書きにしたとき | SQLで下書きにしたとき |
|---|---|---|---|
| 1 | 記事の状態(wp_posts の post_status) | draft になる | draft になる |
| 2 | カテゴリーの記事の数(wp_term_taxonomy の count) | 数え直される | 前の数のまま |
| 3 | サイドバーのカテゴリーの一覧 | 0本なら消える | 残る |
場面3:カテゴリーの記事の数を、SQLで数え直す
公開中の記事だけを数えて、すべてのカテゴリーの count を書き直しました。
sudo mysql wordpress -e "UPDATE wp_term_taxonomy tt SET count = (SELECT COUNT(*) FROM wp_term_relationships tr JOIN wp_posts p ON p.ID = tr.object_id WHERE tr.term_taxonomy_id = tt.term_taxonomy_id AND p.post_status = 'publish' AND p.post_type = 'post') WHERE tt.taxonomy = 'category';"- UPDATE wp_term_taxonomy tt SET count = (…):
カテゴリーの count を、かっこの中で数えた数に書き換える。tt は wp_term_taxonomy の短い呼び名 - wp_term_relationships tr:
どの記事にどのカテゴリーが付いているかを持っているテーブル - JOIN wp_posts p ON p.ID = tr.object_id:
カテゴリーが付いている記事の、状態や種類を見るために wp_posts とつなげる - tr.term_taxonomy_id = tt.term_taxonomy_id:
今書き換えているカテゴリーに付いている記事だけを数える - p.post_status = ‘publish’ AND p.post_type = ‘post’:
公開中の記事(固定ページや画像は除く)だけを数える - WHERE tt.taxonomy = ‘category’:
カテゴリーだけを書き換える(タグなどは触らない)
ページを開き直すと、「Laravel」と「募集終了」がサイドバーから消えていました。
数え直したあとに0本になったのは、「Laravel」「募集終了」「未分類」の3つでした。ほかにも0本と数えられたカテゴリーがありましたが、それは記事をすべて子のカテゴリーに入れている親のカテゴリーです。子のカテゴリーに記事があれば、親もサイドバーに出るので、そのままで問題ありませんでした。
場面4:ずれが残っていないかを確かめる
数え直したあとに、count と、公開中の記事の本当の数がずれているカテゴリーが残っていないかは、次のSQLで確かめられます。
sudo mysql wordpress -e "SELECT * FROM (SELECT t.name, tt.count AS registered, (SELECT COUNT(*) FROM wp_term_relationships tr JOIN wp_posts p ON p.ID = tr.object_id WHERE tr.term_taxonomy_id = tt.term_taxonomy_id AND p.post_status = 'publish' AND p.post_type = 'post') AS published FROM wp_term_taxonomy tt JOIN wp_terms t ON t.term_id = tt.term_id WHERE tt.taxonomy = 'category') x WHERE x.registered <> x.published;"- t.name:
カテゴリーの名前(wp_terms のテーブルに入っている) - tt.count AS registered:
WordPressが覚えている記事の数 - (SELECT COUNT(*) …) AS published:
公開中の記事を、その場で数えた本当の数 - WHERE x.registered <> x.published:
2つの数がちがうカテゴリーだけを出す
何も出なければ、ずれはありません。
場面5:これから決めたこと
この件のあとで、次のように決めました。
- SQLで記事の状態を変えたら、続けて数え直す:
下書きにしたときも、公開に戻したときも、場面3のSQLを続けて流す - カテゴリーそのものは急いで消さない:
記事が0本の「Laravel」「募集終了」は、サイドバーにも出なくなったので、今は残している
まとめ
SQLで記事をまとめて下書きにすると、作業は早く済みます。ただ、WordPressが管理画面の操作のときにだけ行っている数え直しは、SQLでは動きません。今回は、カテゴリーの記事の数が古いまま残り、記事のないカテゴリーがサイドバーに出続けていました。
SQLで記事の状態を変えたら、カテゴリーの記事の数も数え直す。この2つをセットにしておくと、同じことは起きません。
このときに使ったSQLの書き方(UPDATE や JOIN の意味)は、データベースのコマンドの記事で1つずつ説明しています。シェルで結果を確かめたコマンドは、bash のコマンドの記事にまとめました。WordPressのほかの記事は、WordPressのカテゴリーにあります。



コメント