先日、WordPress の開発中にテーマに書かれたSQLを修正する必要が発生しました。
その際に SQL の LEFT JOIN を使った実装をしていて、普段 WP_Query を用いてやっていることの素のコードに触れる機会があったのでまとめておこうと思います。
LEFT JOIN でテーブルを結合
具体的には以下のようなコードになります。
SELECT posts.ID as id
FROM wp_posts AS posts
LEFT JOIN wp_postmeta AS meta ON posts.ID = meta.post_id
WHERE posts.post_type = 'post'
AND posts.post_status = 'publish'
AND meta.meta_key = 'page_type'
上の例は wp_posts と wp_postmeta 2つのテーブルを結合するといったプログラムです。
テーマには wp_posts と wp_usermeta の結合を実装していました。
その場合は下記のように実装。
SELECT posts.ID as id
FROM wp_posts AS posts
LEFT JOIN wp_usermeta AS meta ON posts.ID = meta.meta_key
WHERE 以降の実装は条件に応じてカスタマイズを行う。
具体的にどんな結合をしているの?
プログラムで行われていることがわかりましたが、具体的にどんな結合が行われているのか理解できなかったので、下記コードを図解してみました。
SELECT *
FROM wp_posts AS posts
LEFT JOIN wp_postmeta AS meta ON posts.ID = meta.post_id
先に紹介した posts.ID as id 部分を * に変更しています。
結合後のテーブルが New Table です。
こうして出来上がったテーブルに対して WHERE の条件でフィルターを実施します。
SQL実行後は下記のような結果を得ることができました。
WordPressで実装すると
WordPressで実装すると下記のようになります。
global $wpdb;
$prepared = $wpdb->prepare("SELECT posts.ID as id
FROM wp_posts AS posts
LEFT JOIN wp_postmeta AS meta ON posts.ID = meta.post_id
WHERE posts.post_type = %s
AND posts.post_status = %s
AND meta.meta_key = %s
", 'post', 'publish', 'page_type')
$ID_list = $wpdb->get_results($prepared);
よりWordPressっぽく書くと下記のように書き換えることもできます。
global $wpdb;
$prepared = $wpdb->prepare("SELECT posts.ID as id
FROM {$wpdb->posts} AS posts
LEFT JOIN {$wpdb->usermeta} AS meta ON posts.ID = meta.post_id
WHERE posts.post_type = %s
AND posts.post_status = %s
AND meta.meta_key = %s
", 'post', 'publish', 'page_type')
$ID_list = $wpdb->get_results($prepared);