web-dev-qa-db-ja.com

メタクエリ配列エラー500

MatchPlayerの2つのCPTがあります。各Match投稿エントリには、特定の試合(プレイした人、得点者など)に関する詳細が含まれています。この情報は、個々のPlayerに対応するACF Post Objectフィールドを介して入力されます。しかし、私が達成したいのは、Player投稿ごとに、出現回数、サブ出現回数、目標の合計を生成することです。

これを行うには、次のmeta_queryを使用して、プレーヤーが試合を開始した合計を取得します。クエリは面倒ですが、仕事はします。ただし、私が現在抱えている問題は、同じクエリ構造を使用してサブアピアランスの総数を生成しようとすると、メモリを使い果たしてエラー500を返すことです。

$args = array('post_type'  => 'match',
              'meta_query' => array('relation' => 'OR',
                 array('relation' => 'AND',
                   array('key'=> 'pl12',
                         'value'=> $playerID,
                         'compare'=> '=',),
                   array('key'=> 'si12',
                         'value'=> '0',
                         'compare'=> '!=',),
                   ),
                   array('relation' => 'AND',
                     array('key'=> 'pl13',
                           'value'=> $playerID,
                           'compare'=> '=',),
                     array('key'=> 'si13',
                           'value'=> '0',
                           'compare'=> '!=',),
                   ),
                   ...
                   array('relation' => 'AND',
                     array('key'=> 'pl18',
                           'value'=> $playerID,
                           'compare'=> '=',),
                   array('key'=> 'si18',
                         'value'=> '0',
                         'compare'=> '!=',),
                   ),
                 ),
              );
$subs = new WP_Query( $args );
echo "(".$subs->found_posts.")";
wp_reset_postdata(); 

更新:ソリューション

提案されたfunctions.phpを使用して、カスタムSQLクエリは、Player投稿データを使用して各Matchの合計外観、サブ外観、および目標の出力を提供する信頼できる実用的なソリューションを提供します。

function get_player_stats( $player_id ) {
    global $wpdb;

$stats = [];

$stats['apps'] = (int) $wpdb->get_var( $wpdb->prepare( "
    SELECT COUNT(pm.meta_id) FROM {$wpdb->postmeta} pm
        INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
    WHERE pm.meta_key IN ('PL1','PL2','PL3','PL4','PL5','PL6','PL7','PL8','PL9','PL10','PL11')
        AND pm.meta_value = %d
        AND p.post_type   = 'match'
        AND p.post_status = 'publish'
", $player_id ) );

$stats['subs'] = (int) $wpdb->get_var( $wpdb->prepare( "
    SELECT COUNT(DISTINCT pm.meta_id) FROM {$wpdb->postmeta} pm
        INNER JOIN {$wpdb->postmeta} pm2 ON pm2.post_id = pm.post_id
        INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
    WHERE 1
        AND (
            pm.meta_key IN ('PL12',  'PL13',  'PL14',  'PL15',  'PL16',  'PL17',  'PL18')
            AND pm.meta_value = %d
        )
        AND (
            pm2.meta_key IN ('si12','si13','si14','si15','si16','si17','si18')
            AND ( SUBSTR(pm2.meta_key, 3) = SUBSTR(pm.meta_key, 3) )
            AND pm2.meta_value+0 > 0
        )
        AND p.post_type   = 'match'
        AND p.post_status = 'publish'
    ", $player_id ) );

    $stats['goals'] = (int) $wpdb->get_var( $wpdb->prepare( "
        SELECT COUNT(pm.meta_id) FROM {$wpdb->postmeta} pm
            INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
            WHERE pm.meta_key REGEXP '^S[0-9]+$'
            AND pm.meta_value = %d
            AND p.post_type   = 'match'
            AND p.post_status = 'publish'
    ", $player_id ) );

return $stats;

}

1
Pete Hayman

以前の回答(削除しました)では、カスタムSQLクエリを使用することを提案しました。ただし、うまく機能しなかったので、この関数を使用してみましょう。

function get_player_stats( $player_id ) {
    $apps = 0;  // Total appearances.
    $subs = 0;  // Total sub-appearances.
    $goals = 0; // Total goals.

    // Get all published `match` posts.
    $posts = get_posts( [
        'post_type'      => 'match',
        'posts_per_page' => -1,
    ] );

    foreach ( $posts as $post ) {
        for ( $n = 1; $n <= 18; $n++ ) {
            // Check if the player is $player_id
            $pl = get_post_meta( $post->ID, 'pl' . $n, true );
            if ( $player_id == $pl ) {
                $apps++;

                // Check his sub-out appearance.
                $so = get_post_meta( $post->ID, 'so' . $n, true );
                $subs += $so ? 1 : 0;

                // Check his sub-in appearance.
                $si = get_post_meta( $post->ID, 'si' . $n, true );
                $subs += $si ? 1 : 0;
            }

            // Check if he scored goal {$n}-th.
            $s = get_post_meta( $post->ID, 's' . $n, true );
            if ( $player_id == $s ) {
                $goals++;
            }
        }
    }

    // WP_Query was called; so resets $wp_query
    wp_reset_query();

    return compact( 'apps', 'subs', 'goals' );
}

18人以上のプレーヤーがいる場合(試合中)、18$n <= 18;を正しいプレーヤー数に変更します。例えば20のように$n <= 20;

そして、appssubs、およびgoalsをキーとして連想配列を返すget_player_stats()関数を使用する方法を次に示します。

$stats = get_player_stats( $playerID );
//var_dump( $stats );

echo $stats['apps'] . ' apps, ' .
    $stats['subs'] . ' subs, and ' .
    $stats['goals'] . ' goals.<br>';

この答えがあなたに役立つことを望み、(コードのどの部分でも)明確化が必要かどうかをお知らせください。 =)

1
Sally CJ