web-dev-qa-db-ja.com

カスタムフィールド数を問い合せますか?

次のようなコードがあります。

            <div id="pc" class="smartbar-content">
            <ul class="smartbar-items">
            <?php
            $paged = ( get_query_var('paged') ) ? get_query_var('paged') : 1;
            query_posts( array(
                        'cat' => '6', 
                        'posts_per_page' => 5,
                        'meta_key' => 'krit_karakter',
                        'orderby'=> 'menu_order',
                        'order'=> 'DESC',
                        'caller_get_posts' => 1, 
                        'paged' => $paged ) );
                    if (have_posts()) : while (have_posts()) : the_post(); ?>
                    <li><a href="<?php the_permalink(); ?>"><img src="<?php bloginfo('url');?>/wp-content/files_mf/<?php get_custom_field('game_poster', TRUE); ?>" width="80" height="110" alt="<?php the_title();?>" /> </a>
                    <br /><?php the_title();?></a></li>

                    <?php endwhile; ?>
                    <?php else : endif; ?>
            </ul>
            <?php wp_reset_query(); ?>
        </div>

カスタムフィールド 'krit_karakter'に少なくとも5つのエントリがある投稿のみを表示したいです。

それは可能ですか?

1
Martin-Al

次のコードでは、クエリにwpse4528_keywpse4528_minimumというパラメータを追加してから、キーを使ってメタ値の数をカウントするwhere句に追加の基準を追加します。

add_filter( 'posts_where', 'wpse4528_posts_where', 10, 2 );
function wpse4528_posts_where( $where, &$wp_query )
{
    global $wpdb;
    $count_key = $wp_query->get( 'wpse4528_key' );
    if( $count_key ) {
        $where .= $wpdb->prepare( " AND (SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE {$wpdb->postmeta}.post_id = {$wpdb->posts}.ID AND {$wpdb->postmeta}.meta_key = %s) >= %d", $count_key, $wp_query->get( 'wpse4528_minimum' ) );
    }
    return $where;
}
1
Jan Fabry

Posts_groupbyフィルタを2回使用する必要があります。彼らはおそらくこのように見えるでしょう:

function add_my_groupby($groupby, &$query) {
  global $wpdb;
  $groupby .= "$wpdb->posts.ID";
  return $groupby;
}

function add_my_having($groupby, &$query) {
  $groupby .= " HAVING COUNT(*) >= 5";
  return $groupby;
}

それから、あなたはあなたのテンプレートでそのようなことをする必要があります:

add_filter('posts_groupby', 'add_my_groupby', 10, 2);
add_filter('posts_groupby', 'add_my_having', 1000000, 2);

query_posts( array(/* your stuff...*/) );

remove_filter('posts_groupby', 'add_my_groupby', 10);
remove_filter('posts_groupby', 'add_my_having', 1000000);

(2番目のフィルタの優先順位に渡される極端に大きな数に注意してください。これはWP AP​​Iにposts_havingフィルタがないことを回避するためのものです。)

あるいは、query_posts()ガベージを気にせずに直接DBに問い合わせてください。

$wpdb->get_results("
  SELECT posts.*
  FROM $wpdb->posts as posts
  JOIN $wpdb->postmeta as postmeta
  ON postmeta.post_id = posts.ID
  AND postmeta.meta_key = 'whatever'
  GROUP BY posts.ID
  HAVING COUNT(*) >= 5
  ORDER BY posts.post_date DESC
  LIMIT 5
");

更新日:Janが指摘したように、他の結合がある場合はHAVING COUNT(DISTINCT postmeta.post_id) >= 5のようになります。

1

私はあなたがカスタムフィールドにある種の配列を格納していることを正しく理解しますか?

WordPressが配列をデータベースに保存すると、配列はシリアル化されます(プレーンテキストに変換されます)。 queryはMySQLレベルで機能するため、このようなシリアル化されたデータに対して意味のある操作を実行することはできません。

あなたができることはあなたが別のフィールドで比較したいストアカウント(配列でない値)であり、フィルタリングするのにmeta_compare引数を使うことです。

0
Rarst