2012-04-24 18 views
0

私はターゲットアドレスからの距離順に入力した半径内に投稿タイプを表示するプロジェクトに取り組んでいます。 は今、私は正常に動作し、このクエリを使用しています:
複数のタクソノミーを持つWordpress SQLクエリ

sql = " SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, (" . $_GET['mikm'] . " *   acos(cos(radians($lat)) * cos(radians(wposts.lat)) * cos(radians(wposts.long) - radians($long)) + sin(radians($lat)) * sin(radians(wposts.lat)))) AS distance 
    FROM post_address wposts 
    WHERE wposts.post_type ='" . $post_type . "' 
    HAVING distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page; 


post_addressはポストのID、ポストタイプ、およびアドレスを保持するテーブルです。ポストがアドレスで保存または更新されたときに、このテーブルは情報で更新されます。 私が使用しているフォームにはアドレスのフィールド、ドロップダウンメニューのマイルまたはキロメートル、および距離を選択するチェックボックスがあります。私は、ページ設定のためのフォームでgetメソッドを使用します。

上記のクエリは正常に機能しますが、タクソノミーのサポートを追加しようとしています。今

SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, (" . $_GET['mikm'] . " * acos(cos(radians($lat)) * cos(radians(wposts.lat)) * cos(radians(wposts.long) - radians($long)) + sin(radians($lat)) * sin(radians(wposts.lat)))) AS distance 
FROM post_address wposts 
LEFT JOIN $wpdb->term_relationships ON (wposts.post_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->term_taxonomy.term_id = $wpdb->terms.term_id) 
WHERE wposts.post_type ='" . $post_type . "' 
AND $wpdb->term_taxonomy.taxonomy IN ('" $tax_name "') 
AND ($wpdb->term_taxonomy.parent IN (" . $_GET[$tax_name] . ") OR $wpdb->term_taxonomy.term_id IN (" . $_GET[$tax_name] . ")) 
HAVING distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page; 


、1つの分類作業細かいので、私はそれが複数のタクソノミーで作業したい:私はそれが

wp_dropdown_categories($tax_name) 


とSQLを使用して1つの分類で動作させるために管理しましたそれは私が立ち往生する場所です。たとえば、ポストタイプの "cars"に2つのタクソノミがある場合、 "model"と "color"は、 "this"モデルと "this"カラーを持つ投稿をフィリングすることができます。私はどのくらいのタクソノミーがポストタイプに存在するのか分からず(このプラグインを使用しようとする人は管理者設定で手動で入力するでしょう)、今すぐアレイに保存されています。例えば $分類法=配列( 'car_model'、 'car_color')と私はカテゴリが使用してドロップダウン移入することができます

` 
foreach ($taxonomies as $tax) { 
echo  '<div id="' . $tax . '_cat">'; 
echo  '<label for="category-id">Choose category: </label>'; 
     custom_taxonomy_dropdown($tax); 
echo  '</div>';  
` 



function custom_taxonomy_dropdown($tax_name) { 
$args = array(
     'taxonomy'   => $tax_name, 
     'hide_empty'  => 0, 
     'depth'    => 10, 
     'hierarchical'  => 1, 
     'id'    => $tax_name . '_id', 
     'name'    => $tax_name, 
     'selected'   => $_GET[$tax_name], 
     'show_option_all' => 'All categories', 
     );  
wp_dropdown_categories($args); 
} 


をドロップダウンうまく動作し、出力もURLに送信されますが、私はそれを動作させるSQLクエリを見つけることはできません。

これは私の最初のプロジェクトです。この質問が長く続くのであれば私には言い訳がありますが、私はできる限り明確にしようとしていました。上記のコードのどれかが最善の方法であるかどうかもわかりませんが、誰かの助けがあれば大歓迎です。

UPDATE:以下

は私が今使っているコードであり、それは、複数のタクソノミーで動作します。しかし、私はまだいくつかの問題に陥る。私は分類法のすべてに「すべてのカテゴリ」を選択していたときに、SQLは次のようになります。

AND $wpdb->term_taxonomy.term_id IN() 

とカウントがすべての結果の代わりに何の結果をもたらしませんCOUNT(*)= 0が表示されます。

その他の問題は、子供と孫のカテゴリになります。私が親カテゴリーを選んだとき、私はすべての子供と孫カテゴリーの結果を得ることを期待しています。親には投稿されていないので、子カテゴリには投稿されていないので結果は得られません。 これは今私のコードです:

"SELECT SQL_CALC_FOUND_ROWS DISTINCT wposts.post_id, (" . $_GET['mikm'] . "* acos(cos(radians($lat)) * cos(radians(wposts.lat)) * cos(radians(wposts.long) - radians($long)) + sin(radians($lat)) * sin(radians(wposts.lat)))) AS distance 
     FROM posts_address wposts 
     LEFT JOIN $wpdb->term_relationships ON (wposts.post_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->term_taxonomy.term_id = $wpdb->terms.term_id) 
    WHERE 
    wposts.post_type IN ('" . $post_type . "') 

    AND $wpdb->term_taxonomy.term_id IN (" . $total_terms .") 
    GROUP BY wposts.post_id, wposts.lat, wposts.long   
     HAVING count(*) = " . $bc . " AND distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page ; 

任意のヘルプがにappriciatedされます。

+0

この現象はおそらく、wordpressの場合、カテゴリを選択しないということは、すべてのカテゴリを選択することを意味します。これは問題を提起します。なぜなら、私が説明したアプローチはそこにいくつのカテゴリがあるかを知る必要があるからです。私はカテゴリが選択されていないケースをテストし、すべての分類カテゴリのリストになるようにPHPコード内のクエリパラメータを変更します(すなわち、空のカテゴリを取り除くことは、少なくとも "すべてのカテゴリ"を意味します)。 –

+0

s/emptyカテゴリ最少/空のカテゴリリスト/ –

+0

これは私が今やっていることです。私は、カテゴリが選択されないケースを作成しようとしています。子どもと孫のカテゴリについては少しコードを微調整しています。私はget_term_children()を使ってforeachループを実行して、私が選択した用語が親であるかどうかを確認しなければなりません。私はこれらのidをSQLを実行するために使用します。それ以外の場合は、私が選択した用語を実行します。私はそこに着いている。再度、感謝します。それはこのコミュニティの大歓迎でした。あなたは私をたくさん助けました。 – Eyal

答えて

0

私があなたの要件を正しく読んだら、データベースから分類法に関する情報を抽出する必要はなく、投稿がすべての必要なタクソノミーに「参加」していることを確認するだけです。すべての必要なタクソノミーで投稿に参加し、その後、ラインの乗算結果に基づいてフィルタリングします。 IN演算子に入る引数が囲まれ、カンマ区切り、すべての分類名のリストを生成するようにあなたが

$wpdb->term_taxonomy.taxonomy IN ('" $tax_name "') 

$wpdb->term_taxonomy.parent IN (" . $_GET[$tax_name] . ") OR $wpdb->term_taxonomy.term_id IN (" . $_GET[$tax_name] . ")) 

はそれを持っている

まずステップ、引用によって。例えば:今

$wpdb->term_taxonomy.taxonomy IN ('model_a', 'color_blue') 

、クエリは、ポストが一致していることを(自分のフィルターで)分類法のすべてとの記事を乗算します。ここからは簡単です。投稿フィールド(あなたがクエリで出力したものだけをグループ化する必要があります)でグループ化し、HAVINGを使用してフィルタリングすると、すべてのカテゴリを乗算した投稿のみが返されます。 COUNT(*)フィルタがマッチした分類「軸」の数と一致しなければならないこと

(...) 
GROUP BY wposts.post_id, wposts.lat, wposts.long 
HAVING count(*) = 2 AND (distance <= $radius OR distance IS NULL ORDER BY distance LIMIT " . $from_page . "," . $per_page); 

注:この例では、ポストは、2つのカテゴリ、そうに一致している必要があります。また、タクソノミーに衝突がないと仮定しています(つまり、「青色」モデルと「青色」の色はありません)。

クエリでDISTINCT演算子を削除する必要があります(グループ化では既に異なる投稿が作成されていますが、mysqlのオプティマイザが別個の演算子をいつ計算するかわかりません)。

+0

Sergioありがとう、私はあなたに解決策を試みたが、私はそれを働かせることができなかった。私はtaxonomies $ wpdb-> term_taxonomy.taxonomy( 'model_a'、 'color_blue')を入力するように提案したところでは、term_taxonomy.term_id INで、ドロップダウンリストから選択した用語idを使用する必要があります。その場合、私が選択したモデルか、私が選んだ色のどちらかのポストが表示されます。私はモデルと色を選択した記事だけが必要なときに選択します。 – Eyal

+0

あなたは途中です。グループ化せずにクエリを実行すると、すべての投稿と分類のペアを取得する必要があります。ポストフィールドでグループ化してカウント(*)を生成すると、ポストを取得し、それがどれくらい多くのタクソノミーに一致するかを確認する必要があります。次に、HAVING句にcount(*)条件を追加し、必要なすべての分類に一致する投稿をフィルタリングできます。 –

+0

ありがとう、今回はうまくいった。 "AND(distance ...)"の括弧のために私が試した結果は初めてでした。私はそれらを削除した後、それは働いた。しかし、私はまだいくつかの他の問題に取り組んでいます。私は今使用しているコードと私が持っている問題で私の質問を更新しました。これらの問題に関する追加情報は私にとって非常に役立ちます。私はそれが私の元の質問を解決して以来、あなたは正しい答えとして答えをマークしています。ありがとうございました。 – Eyal

関連する問題