1

さて、私はこのロジックに数週間取り組んできましたが、うまくいくものはまだ作成していません。

私はWordpressを使用しているので、これはクエリを実行する前に文字列(PHPを含む)として保存されます

http://www.libertyguide.com/jobsを見ると、フィルタが表示されます。私がやりたいのはAND、これら 3 つの「カテゴリ」間でフィルタリングを使用することですが、その間でフィルタリングを使用することORです。

例えば:

Academia,Law,Policy, Full-time,Part-time,を選択すると、Early-Career次のフィルタリング ロジックに一致する投稿が得られると予想されます。

ポストがあり(academia OR law OR policy) AND (full-time OR part-time) AND (early-career)ます。

つまり、基本的には学界、法律、または政策に一致する投稿を取得し、フルタイムまたはパートタイムを使用してフィルター処理し、最後にキャリアの早いかどうかをチェックして終了したいと考えています。

上記の例を使用して実行するクエリの例を次に示します。

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)
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') AND... //Rest of query/irrelevant

これでは結果が出ていません。次のようなクエリも試しました (上記の例と同じであるため、最初の 5 行は省略されています)。

WHERE
    wp_term.slug IN ('academia','law','policy') AND
    wp_term.slug IN ('full-time','part-time') AND
    wp_term.slug IN ('early-career') AND ... //Rest of query

これは、1 つの「カテゴリ」で項目が選択されている場合にのみ結果を返します。カテゴリ間では機能しません。私はまだクエリが少し間違っていると思います。私は以前にいくつかの解決策を得ました (これらはどちらも私に最も近いと信じている解決策です) が、それらには抜け穴があります。

HAVING COUNTその場合、すべてをANDフィルターにする可能性があるため、使用しないでください。これは私が望んでいるものではありません。

どんな助けでも大歓迎です。うまくいけば、問題を補うために何かを考えてもかまいません。

ありがとう!

4

3 に答える 3

4

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_taxonomy3つの異なるエイリアスを使用して、テーブルと複数回結合する必要がある可能性があります。

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

その他。

于 2012-05-02T04:19:44.763 に答える
0

INをEXISTSに変更します。それを試してみてください—あなたはあなたの結果を得るでしょう。

WHERE 
    wp_term_taxonomy.term_id exists (SELECT term_id FROM wp_terms 
        WHERE slug='academia' OR slug='law' OR slug='policy') AND
    wp_term_taxonomy.term_id exists(SELECT term_id FROM wp_terms 
        WHERE slug='full-time' OR slug='part-time') AND
    wp_term_taxonomy.term_id exists (SELECT term_id FROM wp_terms 
        WHERE slug='early-career') AND... //Rest of query/irrelevant
于 2012-05-02T04:19:24.440 に答える
0

またはを使用:

wp_term_taxonomy.term_id IN (SELECT term_id FROM wp_terms 
    WHERE slug='academia' OR slug='law' OR slug='policy') 

OR wp_term_taxonomy.term_id IN (SELECT term_id FROM wp_terms 
    WHERE slug='full-time' OR slug='part-time') 

OR wp_term_taxonomy.term_id IN (SELECT term_id FROM wp_terms 
    WHERE slug='early-career') AND... //Rest of query/irrelevan

クエリを分析すると、次のようになります。

wp_term_taxonomy.term_id IN (SELECT term_id FROM wp_terms 
    WHERE slug='academia' OR slug='law' OR slug='policy'
       OR slug='full-time' OR slug='part-time'
       OR slug='early-career') 
于 2012-05-02T04:26:20.907 に答える