0

I have a custom post type with the fields Exercise and Tempo. Here is an example of how that might look:

Exercise 1 - 100
Exercise 2 - 104
Exercise 3 - 96
Exercise 1 - 104
Exercise 2 - 110
Exercise 3 - 100

How might I use WP_Query to return only the highest Tempo of each Exercise?

The desired result would be:

Exercise 1 - 104
Exercise 2 - 110
Exericse 3 - 100

EDIT:

I finally got it working (see below) with the way that Rarst suggested. Thanks for the help!

 function opl_user_practice_sheet_test($atts, $content = null){

if ( is_user_logged_in()) {
global $current_user;
wp_get_current_user();
echo 'User: ' . $current_user->user_login . "\n";

global $post;

$atts = shortcode_atts( array(
'title'           => 'User Practice Sheet',
'count'           => -1
), $atts);

// query arguments
$args = array(
'post_type'       => 'opl_exercise',
'post_status'     => 'publish',
'orderby'         => 'created',
'order'           => 'DESC',
'posts_per_page'  => $atts['count']
);

// fetch practice sheet tempos
$practice_sheet_exercises = new WP_Query($args);

// check if tempos come back
if($practice_sheet_exercises->have_posts()){

// init output
$output = '';

// build output
$output .= '<div class="user-practice-sheet">
              <table>
                <thead>
                  <tr>
                    <td>Exercise</td>
                    <td>Submitted Tempo</td>
                    <td>Next Target Tempo</td>
                  </tr>
                </thead>
                <tbody>';

while($practice_sheet_exercises->have_posts()){

  $practice_sheet_exercises->the_post();

  $exercise_type = get_post_meta($post->ID, 'opl_exercise_type', true);
  $exercise_number = get_post_meta($post->ID, 'opl_exercise_number', true);


  $tempo_query = new WP_Query(
    array(
      'post_type'       => 'opl_tempo_submission',
      'order_by'        => 'meta_value_num',
      'meta_key'        => 'opl_submission_tempo',
      'order'           => 'DESC',
      'posts_per_page'  => 1,
      'meta_query'      => array(
        'relation' => 'AND',
        array(
          'key' => 'opl_submission_exercise_type',
          'value' => $exercise_type,
          'compare' => '='
        ),
        array(
          'key' => 'opl_submission_exercise_number',
          'value' => $exercise_number,
          'compare' => '='
        )
      )
    )
  );

  if ( $tempo_query->have_posts() ) {
      while ( $tempo_query->have_posts() ) {

        $tempo_query->the_post();

        $submission_tempo = get_post_meta($post->ID, 'opl_submission_tempo', true);

  $output .= '<tr>';

  $output .= '<td>'.$exercise_type .' '. $exercise_number.'</td>';
  $output .= '<td>'.$submission_tempo.'</td>';
  $output .= '<td></td>';

  $output .= '</tr>';

     }

  }


}

$output .= '</tbody>
            </table>
            </div>';

// reset post data
wp_reset_postdata();

return $output;

} else {
return '<p>No Practice Sheet Found</p>';
}

}
}
1
  • If you're still in the process of building this system it would probably be easier to store these numbers as postmeta so you can order numerically by said postmeta value. As it seems now you're putting the temp ( number you need to orderby ) into the title field.
    – Howdy_McGee
    May 20, 2016 at 14:24

2 Answers 2

0

If I get this right each of your posts have one value of Exercise and one Value of Tempo?

I would do the following probably:

  1. Build a list of exercises.
  2. For each exercise query query: 1 posts, ordered by Tempo, descending.

This is probably as good as it gets staying within realm of WP API. Might not be practical for high counts of Exercises, it's all custom SQL from there.

5
  • That definitely makes sense. In your opinion, what would you consider a high count?
    – AHinson
    May 20, 2016 at 14:24
  • Hard to say, depends on your data size and such. I would say if talking dozens you are probably ok, hundreds and it's probably time to think about custom SQL or at least caching.
    – Rarst
    May 20, 2016 at 14:32
  • So I've been messing around with it and I can't quite seem to set this up in the way you are describing. Would you possibly be able to expand on it just a little bit?
    – AHinson
    May 20, 2016 at 16:19
  • Please update your question with your progress, always a good move. :)
    – Rarst
    May 20, 2016 at 16:24
  • Done! Not sure if this is the right direction though.
    – AHinson
    May 20, 2016 at 17:10
0

You first have to build a query for your posts, and inside that query you would get all your custom fields and compare them.

You could use a plugin like CMB2 to build repeatble grouped fields so you can get the exercises grouped (all Excercises1, all Excercises2, etc) and also asign each to have a TEMPO field attached to that group. It would be easier then to query and compare them and get the higher one.

<?php

$args = array(

    'post_type' => POST_TYPE_NAME

);

$the_query = new WP_Query( $args );

if ( $the_query->have_posts() ) {

    while ( $the_query->have_posts() ) {
        $the_query->the_post();
        //Here you would query your grouped fields and then compare and return the higher TEMPO

    }

}
else {

}

wp_reset_postdata();

?>
1
  • Oh ok great. I'll look into CMB2. Thanks for the input!
    – AHinson
    May 20, 2016 at 12:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.