WHERE句だけを使用すると、いくつかの問題が発生する可能性があります。
WHERE wp_term_taxonomy.term_id IN (SELECT term_id FROM wp_terms
WHERE slug='academia' OR slug='law' OR slug='policy')
AND wp_term_taxonomy.term_id IN (SELECT term_id FROM wp_terms
WHERE slug='full-time' OR slug='part-time')
AND wp_term_taxonomy.term_id IN (SELECT term_id FROM wp_terms
WHERE slug='early-career')
ここではwp_term_taxonomy.term_id
、アカデミア、法律、またはポリシーのいずれかの用語ID(おそらく3つの異なる値)と同時に、フルタイムまたはパートタイムのいずれかの用語IDと同じである必要がある単一の列()があります。 (おそらく2つの異なる値であり、前の3つの値のそれぞれとは異なります)また、Early-Careerの用語IDと同じです(1つの値ですが、前の5つの値のそれぞれとは異なります。したがって、単一の用語IDは一度に3つの異なる値であり、それを管理することはできません。
wp_term_taxonomy
3つの異なるエイリアスを使用して、テーブルと複数回結合する必要がある可能性があります。
WHERE wtt1.term_id IN (SELECT term_id FROM wp_terms
WHERE slug='academia' OR slug='law' OR slug='policy')
AND wtt2.term_id IN (SELECT term_id FROM wp_terms
WHERE slug='full-time' OR slug='part-time')
AND wtt3.term_id IN (SELECT term_id FROM wp_terms
WHERE slug='early-career')
ここで、私が使用した3つのエイリアスは、、、wtt1
およびwtt2
ですwtt3
。それらはJOIN条件にリストされます。
選択リストとFROM句を見てみましょう
SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
LEFT JOIN $wpdb->terms ON($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id)
次に、通常のSQLを残して、PHPマテリアルの一部を解きほぐしてみましょう。
SELECT *
FROM wp_posts AS p
LEFT JOIN wp_postmeta AS pm ON p.ID = pm.post_id
LEFT JOIN wp_term_relationships AS tr ON p.ID = tr.object_id
LEFT JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
LEFT JOIN wp_terms AS tm ON tm.term_id = tt.term_id
おそらく、ここに左結合は必要ありません。基準に一致しない投稿は表示したくありませんが、LEFT JOINを使用すると、この部分で多くの投稿が選択されます(ただし、すべての行は、すでに説明した壊れたWHERE条件によって後で破棄されます)。
1つの投稿に複数の用語関係エントリが含まれる場合があります。少なくとも3つの用語関係エントリを持つ投稿が必要です。1つはアカデミア/法律/ポリシートリオ用、もう1つはフルタイム/パートタイムデュオ用、そしてアーリーキャリア用です。
SELECT *
FROM wp_posts AS p
JOIN wp_postmeta AS pm ON p.ID = pm.Post_ID
JOIN (SELECT t1.Object_ID
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('academia', 'law', 'policy')
) AS t1 ON p.ID = t1.Object_ID
JOIN (SELECT t1.Object_ID
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('full-time', 'part-time')
) AS t2 ON p.ID = t2.Object_ID
JOIN (SELECT t1.Object_ID
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug = 'early-career')
) AS t3 ON p.ID = t3.Object_ID
それでうまくいくかもしれないと思いますが、遅くなっていて、完全に壁から外れる可能性があります。それは確かに書かれたような単純なクエリではありません。
基本的なSQLが正しいと仮定すると、テーブル名をPHP表記に置き換えるだけです。
SELECT *
FROM $wpdb->posts AS p
JOIN $wpdb->postmeta AS pm ON p.ID = pm.Post_ID
JOIN (SELECT t1.Object_ID
FROM $wpdb->term_relationships AS tr
JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN $wpdb->terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('academia', 'law', 'policy')
) AS t1 ON p.ID = t1.Object_ID
JOIN (SELECT t1.Object_ID
FROM $wpdb->term_relationships AS tr
JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN $wpdb->terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('full-time', 'part-time')
) AS t2 ON p.ID = t2.Object_ID
JOIN (SELECT t1.Object_ID
FROM $wpdb->term_relationships AS tr
JOIN $wpdb->term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN $wpdb->terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug = 'early-career')
) AS t3 ON p.ID = t3.Object_ID
どのDBMSが使用されているかはわかりませんが、MySQLである可能性があります。Oracleを使用している場合は、ASをテーブルエイリアスから除外する必要があります。標準SQLおよび他のほとんどのSQLDBMSは、テーブルエイリアスのASで問題ありません。$wpdb->
表記の使用がテーブルエイリアスの使用によってどのように制限されているかに注意してください。コードが読みやすくなります(ただし、まだ読みやすくはありません)。
バグ修正と問題解決
テストされていないコードには通常バグがあります。これは、他のテストされていないコードと同じです。
最初のテストステップは、FROM句のサブクエリを個別に実行することでした。それはすぐに彼らが参照するべきではないことを示しましたt1.Object_ID
; いずれの場合もそうする必要がありますtr.Object_ID
。「初期のキャリア」の後には、無関係な右括弧もありました。(サブ)クエリを実行するためのテストデータベースがあれば、これらの間違いは簡単に見つかりました。
SELECT *
FROM wp_posts AS p
JOIN wp_postmeta AS pm ON p.ID = pm.Post_ID
JOIN (SELECT tr.Object_ID
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('academia', 'law', 'policy')
) AS t1 ON p.ID = t1.Object_ID
JOIN (SELECT tr.Object_ID
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('full-time', 'part-time')
) AS t2 ON p.ID = t2.Object_ID
JOIN (SELECT tr.Object_ID
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug = 'early-career'
) AS t3 ON p.ID = t3.Object_ID
これらの修正が行われると、クエリが実行され、データの行が生成されました。結果の3つのサブクエリからのスラッグが必要であると合法的に決定する場合があります。サブクエリを変更してを返しtr.Object_ID, tm.slug
ます。たとえば、クエリのこのバリアントは次のとおりです。
SELECT p.ID, t1.slug_1, t2.slug_2, t3.slug_3, pm.meta_key
FROM wp_posts AS p
JOIN wp_postmeta AS pm ON p.ID = pm.Post_ID
JOIN (SELECT tr.Object_ID, tm.slug AS slug_1
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('academia', 'law', 'policy')
) AS t1 ON p.ID = t1.Object_ID
JOIN (SELECT tr.Object_ID, tm.slug AS slug_2
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('full-time', 'part-time')
) AS t2 ON p.ID = t2.Object_ID
JOIN (SELECT tr.Object_ID, tm.slug AS slug_3
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug = 'early-career'
) AS t3 ON p.ID = t3.Object_ID;
いくつかのテストデータで次の結果が得られました。
1575 policy full-time early-career date_legible
1575 policy full-time early-career date_timestamp
1575 policy full-time early-career longitude
1575 policy full-time early-career date_normal
1575 policy full-time early-career url
1575 policy full-time early-career _su_rich_snippet_type
1575 policy full-time early-career _edit_last
1575 policy full-time early-career expiration-date
1575 policy full-time early-career organization
1575 policy full-time early-career latitude
1575 policy full-time early-career location
1575 policy full-time early-career _edit_lock
これは、必要な3つの特性を持つ投稿(ID = 1575)が少なくとも1つあることを示していますが、PostMetaデータをより巧妙に処理する必要があることも示しています。結果は、PostMetaがEAV(Entity-Attribute-Value)モデルであることを示唆しています。これには、特定の投稿の有用な情報(緯度や経度など)を取得するための慎重な処理が必要になります。実際、調べたい個別のメタ属性ごとに1つの(場合によっては外部の)結合が必要になります。
たとえば、投稿の緯度と経度を収集するには、次のように入力する必要があります。
SELECT p.ID, t1.slug_1, t2.slug_2, t3.slug_3, p1.latitude, p2.longitude
FROM wp_posts AS p
LEFT JOIN
(SELECT Post_ID, Meta_Key AS m1_key, Meta_Value AS latitude
FROM wp_postmeta
WHERE Meta_Key = 'latitude'
) AS p1 ON p.ID = p1.Post_ID
LEFT JOIN
(SELECT Post_ID, Meta_Key AS m2_key, Meta_Value AS longitude
FROM wp_postmeta
WHERE Meta_Key = 'longitude'
) AS p2 ON p.ID = p2.Post_ID
JOIN (SELECT tr.Object_ID, tm.slug AS slug_1
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('academia', 'law', 'policy')
) AS t1 ON p.ID = t1.Object_ID
JOIN (SELECT tr.Object_ID, tm.slug AS slug_2
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug IN ('full-time', 'part-time')
) AS t2 ON p.ID = t2.Object_ID
JOIN (SELECT tr.Object_ID, tm.slug AS slug_3
FROM wp_term_relationships AS tr
JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
JOIN wp_terms AS tm ON tm.term_id = tt.term_id
WHERE tm.slug = 'early-career'
) AS t3 ON p.ID = t3.Object_ID;
生成するもの:
1575 policy full-time early-career -33.8210366 151.1887557
その他。