WEBOPIXEL

WordPressで学ぶデータベース(MySQL)の基礎[リレーション編]

Posted: 2017.12.12 / Category: WordPress, データベース 

前回に引き続きWordPressでMySQLを学んで見ます。
前回は単一テーブルでの検索でしたが、今回は複数のテーブルを結合させて検索する方法を学んでいきます。

Sponsored Link

ユーザー情報の表示(wp_users)

ユーザー名などのユーザー情報が保存されているテーブルはwp_usersになります。
このテーブルとポストwp_postsを結合してみましょう。

記事一覧にユーザー情報を表示

テーブルの結合はJOIN句にテーブル名。ON句に結合条件を記述します。
条件はwp_postspost_authorがユーザーIDになるので、これとwp_usersIDと結びつけます。

wp_postsとwp_usersの関連図
SELECT * FROM wp_posts
JOIN wp_users
ON wp_posts.post_author = wp_users.ID

指定ユーザーの記事を検索

テーブルを結合した後は普通にWHEREで条件を指定できます。
user_loginがadminを検索したい場合は下記のようにします。

SELECT * FROM wp_posts
JOIN wp_users
ON wp_posts.post_author = wp_users.ID
WHERE user_login = "admin"

SELECTの詳細選択と別名

ソースコード省略のためSELECTには*ですべてのカラムを選択してますが、通常はカラムを指定することになると思います。
しかし、複数のテーブルを選択すると単純にIDと指定しても、どのテーブルのIDかわからないですね。
その為、複数のテーブルを扱うときはSELECTには「テーブル名.カラム名」のような記述にします。

SELECT wp_posts.ID, wp_posts.post_title, wp_posts.post_date, wp_users.display_name

テーブル名(wp_posts)を何度も書かなくてはいけないので長いとめんどいですよね。FROM後にASで別名を付けて短縮してみましょう。

SELECT p.ID, p.post_title, p.post_date, u.display_name
FROM wp_posts AS p
JOIN wp_users AS u
ON u.ID = p.post_author

だいぶすっきりしましたね。

カテゴリー・タグで検索(wp_terms)

WordPressはカテゴリーやタグはまとめてタームと呼ばれたりもします。
タームは一つの記事に複数のタームが関連付けされる可能があります。
リレーショナルデータベースではこの場合、テーブルとテーブルの間に関連付けするだけの中間テーブルを作ることが多いです。

WordPressの場合ターム情報はwp_postswp_term_taxonomyの中間テーブルとしてwp_term_relationshipsテーブルがあり、さらにwp_termsに名称などの記載があります。
その他にカスタムフィールド用のテーブルwp_termmetaがあり、ターム関係のテーブルだけで4つのテーブルがあります。

wp_postsとwp_termsの関連図

ターム名で検索したい場合はwp_termmeta以外の4つを結合します。
ターム名のWordPressに属している投稿を検索する場合は次のようになります。

SELECT p.ID, p.post_title, p.post_date
	FROM wp_posts AS p
JOIN wp_term_relationships AS tr
	ON tr.object_id = p.ID
JOIN wp_term_taxonomy AS tt
	ON tt.term_taxonomy_id = tr.term_taxonomy_id
JOIN wp_terms AS t
	ON t.term_id = tt.term_id
WHERE p.post_type = "post"
	AND p.post_status = "publish"
	AND t.name = "WordPress"

カスタムフィールドで検索(wp_postmeta)

カスタムフィールドはwp_postmetaテーブルに保存されています。
このテーブルはpost_idが投稿のIDになっているのでwp_postsIDと結合します。

wp_postsとwp_postmetaの関連図

例えばpriceというカスタムフィールドの値が1000以上の投稿を検索したい場合は次のようになります。

SELECT DISTINCT p.ID, p.post_title, p.post_date, meta.meta_value
	FROM wp_posts AS p
LEFT JOIN wp_postmeta AS meta
	ON meta.post_id = p.ID
WHERE meta.meta_key = "price"
	AND meta.meta_value > 1000
WordPressで学ぶデータベース(MySQL)の基礎