web-dev-qa-db-fra.com

Comparer deux champs personnalisés numériques

J'utilise Advanced Custom Fields et j'ai un "match" de type custompost. Ce post-type contient deux champs "objectifs" et "objectifs".

Je veux interroger wordpress pour ne montrer que les résultats obtenus. Alors, où "buts"> "buts contre".

Quelqu'un peut-il m'aider à démarrer avec celui-ci. L'objectif est d'avoir une page de statistiques à la fin.

Merci beaucoup pour m'aider

3
Mister Melotte

Si j'étais dans votre situation, j'aurais utilisé une approche différente.

Ajoutez simplement un champ méta masqué automatiquement lorsque les objectifs_made sont mis à jour.

Par exemple.

add_action('updated_postmeta', 'update_goal_made', 20, 4);

function update_goal_made( $meta_id, $object_id, $meta_key, $_meta_value ) {
  if ( $meta_key != 'goals-made') return; // run only when update meta 'goals-made'
  // get the goals-against for post
  $against = get_post_meta($object_id, 'goals-against', true) ? : 1;
  // if 'goals-made' > 'goals-against' create/update a field '_goals-won' setted to 1
  if ( intval($_meta_value) > intval($against) ) {
    update_post_meta($object_id, '_goals-won', '1');
  } else {
    // if not delete '_goals-won' post meta (if exists)
    delete_post_meta($object_id, '_goals-won');
  }
}

Maintenant, pour récupérer les publications où _goals-won existe, lancez simplement une méta-requête:

$args = (
  'posts_per_page' => -1,
  'meta_query' => array( array('meta_key'=>'_goals-won') )
);
$won_posts = get_posts($args);

MODIFIER

Après quelques travaux sur GhostToast answer je peux également vous donner la bonne requête SQL pour obtenir le même résultat.

global $wpdb;
$won_posts = $wpdb->get_results( "
    SELECT $wpdb->posts.* 
        FROM $wpdb->posts
    INNER JOIN $wpdb->postmeta AS mt1 ON ( $wpdb->posts.ID = mt1.post_id )
    INNER JOIN $wpdb->postmeta AS mt2 ON ( $wpdb->posts.ID = mt2.post_id )
    WHERE mt1.meta_key = 'goals-made' 
        AND ( 
            mt2.meta_key = 'goals-against'
            AND CAST( mt1.meta_value AS UNSIGNED ) > CAST( mt2.meta_value AS UNSIGNED )
        )
    GROUP BY $wpdb->posts.ID
" );

Note latérale:

Si quelqu'un écrit l'instruction SQL qui traite votre demande, sûr que l'instruction SQL sera moins performante que la méta-requête la plus simple comme la première postée.

4
gmazzap

Je pense que quelque chose comme ça, mais pas testé, et mon SQL-foo est plutôt faible:

    $test = $wpdb->get_col( $wpdb->prepare(
    "
    SELECT DISTINCT    $wpdb->posts.*
    FROM               $wpdb->posts
    INNER JOIN         $wpdb->postmeta AS mt1 ON (
         wp_posts.ID = $wpdb->postmeta.post_id
    )
    WHERE              $wpdb->postmeta.meta_key = 'goals-made'
    AND(               mt1.meta_key = 'goals-against'
        AND            CAST($wpdb->postmeta.meta_value AS INT) > CAST(mt1.meta_value AS INT)
    )

    "
));

Cela devrait renvoyer une liste de post_ids que vous pouvez ensuite traiter. Mais là encore, il pourrait bien échouer lamentablement.

4
GhostToast

J'espère que je n'ai pas compris la mauvaise question :)

$results = new WP_Query( array(
    'post_type'  => 'matches',
    'meta_query' => array(
        array(
            'key'     => 'goals-made',
            'value'   => (int) get_post_meta( get_the_ID(), 'goals-against',  true ),
            'type'    => 'INT',
            'compare' => ">",
        )
    ),
) );
if ( $results->have_posts() )
{
    while ( $results->have_posts() )
    {
        the_post();
        var_dump( $GLOBALS['post'] );
    }
}

Comme nous ne savons pas d'où vous faites cette requête, il vous suffit de remplacer get_the_ID() dans get_post_meta() par l'ID récupéré des publications que vous souhaitez comparer.

2
kaiser

Peut-être que je ne comprends pas la question non plus, parce que la réponse est évidente pour moi. Je suppose que c'est pour un poste, donc vous auriez 2 champs personnalisés, foo et bar.

Donc, dans le code ...

$foo = get_field('foo');
$bar = get_field('bar');
if ($foo > $bar) {
    echo 'foo is greater than bar';
} else {
    echo 'bar is greater than foo';
}
0
John