8. Copyright 2016-2018 G1Systems Inc.
つまり、これはバグ(外部結合が必要か判別不能)
8
SELECT
a.氏名, b.ランク
FROM 生徒マスタ a
LEFT OUTER JOIN 特待生マスタ b
ON a.ID = b.生徒ID
WHERE
b.削除フラグ = 0;
外部結合を打消し
てしまう。
9. Copyright 2016-2018 G1Systems Inc.
例えば、WordPress 4.9.4 での例
if ( $post_status_join ) {
$join .= “ LEFT JOIN {$wpdb->posts} AS p2 ON
({$wpdb->posts}.post_parent = p2.ID)";
foreach ( $statuswheres as $index => $statuswhere ) {
$statuswheres[$index] =
"($statuswhere
OR ({$wpdb->posts}.post_status = 'inherit’
AND ".str_replace( $wpdb->posts, 'p2', $statuswhere ) . "))";
}
}
$where_status = implode( ' OR ', $statuswheres );
if ( ! empty( $where_status ) ) {
$where .= " AND ($where_status)";
} ※ class-wp-query.php
9
10. Copyright 2016-2018 G1Systems Inc.
WordPress 4.9.4 は、最後に LEFT JOIN に変換
/** Generates SQL clauses to be appended to a main query.
-- 中略 --
public function get_sql( $type, $primary_table, ……
-- 中略 --
/* If any JOINs are LEFT JOINs (as in the case of NOT EXISTS), then all JOINs should be
LEFT. Otherwise posts with no metadata will be excluded from results. */
-- 中略 --
if ( false !== strpos( $sql['join'], 'LEFT JOIN' ) ) {
$sql['join'] = str_replace( 'INNER JOIN', 'LEFT JOIN', $sql['join'] );
}
-- 中略 -- ※ class-wp-meta-query.php
10
12. Copyright 2016-2018 G1Systems Inc.
一応、Word Press がやっている変換意図を解説
12
生徒マスタ 特待生マスタ
2 C
生徒ID ランク
3 A
(4) NULL
(5) NULL
(6) NULL
1石野 扶樹
ID氏名
2岩崎 研二
3岩間 竜也
4上野 浩介
5岡崎 雅之
6岡島 慶二
1
削除フラグ
0
NULL
NULL
NULL
10 B
33 C
40 B
0
0
0
(1) NULLNULL
ランク名称マスタ
学業特待生AA
名称ランク
学業特待生BB
スポーツ特待生C
こちらINNER JOIN にすると、
B・Cに一致するものがない
ため、外部結合を打消してし
まう。こちらを LEFT JOIN
13. Copyright 2016-2018 G1Systems Inc.
サブクエリ にすると正しく出ます
13
SELECT
a.氏名, b.ランク
FROM 生徒マスタ a
LEFT OUTER JOIN
(SELECT * FROM 特待生マスタ
WHERE 削除フラグ = 0) b
ON a.ID = b.生徒ID;
23. Copyright 2016-2018 G1Systems Inc.
つまりサブクエリではなく、こうする!
23
SELECT
a.氏名, b.ランク
FROM 生徒マスタ a
LEFT OUTER JOIN 特待生マスタ b
ON a.ID = b.生徒ID
AND 0 = b.削除フラグ;
24. Copyright 2016-2018 G1Systems Inc.
有効期限のときはこうする!
24
SELECT
a.氏名, b.ランク
FROM 生徒マスタ a
LEFT OUTER JOIN 特待生マスタ b
ON a.ID = b.生徒ID
AND 基準日 >= b.有効期限From
AND 基準日 <= b.有効期限To;