3

I'm using custom post types to display properties and have a custom price field assigned to each post. On the property page I want to display a list of four similarly priced properties, two less than or equal to the price of the current property and two greater than the current price. Ordering properties numerically by price is easy enough with wp_query, but how do I only display the closest values to the price of the current property?

2 Answers 2

2

One possibility is a direct SQL query similar to the one given here.

But I'm not convinced that it would be much more efficient than 2 queries, all handled by WordPress:

The is untested

$price =0; //Price of current property
$id=0; //Property (post) ID.

$args = array(
    'post_type' => 'property',
    'post__not_in'=>array($id),
    'posts_per_page'=> 2,
    'meta_query' => array(array(
        'key' => 'price',
        'value' => $price,
        'type' => 'numeric',
        'compare' => '>='
        )),
     'meta_key'=> 'price',
     'orderby'=>'meta_value_num',
     'order'=>'ASC'
    );

 $two_above = get_posts($args);

 //Put their IDs along with current property ID in an array
 $ids = array_values(wp_list_pluck($two_above, 'ID'));
 array_push($ids, $id);

 //Exclude returned properties and current property from next query
 $args['post__not_in'] = $ids;

 $args['meta_query']['compare'] = '<=';
 $args['order'] = 'DESC';

 $two_below = get_posts($args);
5
  • This is great! So far it's working perfectly in my testing. The only thing I changed was to remove the second order arg (DESC) as the ordering stays the same, it's just starting from a different point. Beyond what you have here I just used an array_merge (a first for me) on the output so I could loop through all the posts in one go. All of which makes me very happy. Thanks a ton!
    – Sam
    May 11, 2012 at 16:58
  • Glad its working... but are you sure it stays ASC? In the second query you want the first two results to have the highest price, so surely its DESC? May 11, 2012 at 17:20
  • So I tested this with more data and found it wasn't working. The code seemed right no matter how I looked at it, so I spent quite a bit of time banging my head against the wall and trying to figure out if other loops were interfering or something. Turns out the solution is pretty simple: the meta_query array needs to contain a additional array. Once I updated the code to reflect that everything worked like a charm.
    – Sam
    Jun 8, 2012 at 16:31
  • @Sam You're right! Sorry about that... I've corrected the code. Jun 8, 2012 at 19:35
  • No worries. Would not have figured this solution out without you!
    – Sam
    Jun 14, 2012 at 18:50
-1

Edit

Thanks for calling me out, it's the only way to get better.

The updated query would look like this:

$args = array(
    'post_type' => 'POST',
    'meta_query' => array(
        'key' => 'PRICE',
        'value' => array( ($price - 2), ($price + 2)),
        'type' => 'numeric',
        'compare' => 'BETWEEN'
        );
    );

Thanks again, kaiser for making me do the right thing.


The quickest thing to do is to create your own query using $wpdb. The most basic function would look like this:

function my_custom_get ($price) {
    global $wpdb;
    $min_price = $price - 2;
    $max_price = $price + 2;

    $sql_query = "
        SELECT $wpdb->posts.* 
        FROM $wpdb->posts, $wpdb->postmeta
        WHERE $wpdb->posts.ID = $wpdb->postmeta.post_id 
        AND $wpdb->postmeta.meta_key = 'PRICE' 
        AND $wpdb->postmeta.meta_value < $max_price
        AND $wpdb->postmeta.meta_value > $min_price
        AND $wpdb->posts.post_status = 'publish' 
        AND $wpdb->posts.post_type = 'PRODUCT'
        AND $wpdb->posts.post_date < NOW()
        ORDER BY $wpdb->posts.post_date DESC
        ";
    return $wpdb->get_results($querystr, OBJECT);
}

Don't forget to change the values of meta_key and post_type to fit your specific application. Hope this helps!

2
  • 1
    A) There's $wpdb->prepare() to make queries safer. B) You can do meta_query and use BETWEEN as comparison value.
    – kaiser
    May 10, 2012 at 20:01
  • This would get all properties with a price within +/- the current property's price. The OP wants only 4 properties, whose price is closest to that of the current property - 2 more than, 2 less than. May 11, 2012 at 1: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.