Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Is it possible using WP_Query to return a filtered list of items based on the following criteria set? I seem to be struggling as there are numerous queries against custom fields.

Select all posts that are of type business_club (post_type)
Where the post has a zone of 'Asia' (meta_value)
Order by country ASC (meta_value)
then by town ASC (meta_value)
then by title (wp value)

Any help is greatly appreciated.

share|improve this question
add comment

3 Answers

up vote 1 down vote accepted

The way around it was to build a custom query. More information on this can be viewed on the Wordpress codex at http://codex.wordpress.org/Displaying_Posts_Using_a_Custom_Select_Query.

My final code looked as follows

<?php               
$row = 0;
$zone = $_GET['zone'];
if (!$zone) $zone = "United Kingdom";
?>

<table class="formattedTable" cellspacing="1" cellpadding="0">
<tr>
    <th width="140">Country</th>
    <th width="140">Town</th>
    <th>Club</th>
</tr>
<?php

$query = "
SELECT
  posts.*
FROM
  $wpdb->posts posts
INNER JOIN
  $wpdb->postmeta meta1 ON posts.ID = meta1.post_ID
INNER JOIN
  $wpdb->postmeta meta2 ON posts.ID = meta2.post_ID
INNER JOIN
  $wpdb->postmeta meta3 ON posts.ID = meta3.post_ID
WHERE
  posts.post_type = 'club' AND
  posts.post_status = 'publish' AND
  meta1.meta_key = '_club-zone' AND
  meta1.meta_value = '$zone' AND
  meta2.meta_key = '_club-country' AND
  meta3.meta_key = '_club-town'
ORDER BY
  meta2.meta_value,
  meta3.meta_value,
  posts.post_title";

$posts = $wpdb->get_results($query, object);        
if ($posts)
    foreach($posts as $post)
    {
        global $post;
        setup_postdata($post);

        echo '<tr class="' . ($row % 2 == 0 ? 'odd' : 'even') . '">';
        echo '<td>' . get_post_meta(get_the_ID(), '_club-country', true) . '</td>';
        echo '<td>' . get_post_meta(get_the_ID(), '_club-town', true) . '</td>';
        echo '<td><a href="' . get_permalink(get_the_ID()) . '">' . get_the_title() . '</a></td>';
        echo '</tr>';
        $row++;
    }

?>
</table>
share|improve this answer
add comment

If all results have the same zone, why would you want to order by zone?

As far as I know, you can't include two meta_keys in a single query. So you'll have to write the query to return the results ordered by title, save them in an array, and then resort the array into the order you need using PHP.

share|improve this answer
    
That was a mistake in the pseudo-code sample Gabriel, I've updated the example. Do you have any examples of sorting after the resultset has been returned? –  WDuffy Jan 10 '11 at 9:13
add comment

Did you try something like this:

$loop = new WP_Query( array( 
    'post_type' => 'business_club',
    'meta_value' => 'United Kingdom',
    'order' => 'ASC',
    'orderby' => 'meta_value',
    'meta_key' => 'zone'
 ) ); 
while ( $loop->have_posts() ) : $loop->the_post();

I don't know yet if you can do the then orderby town and title.

share|improve this answer
    
You'd have to do a custom join and a custom order by using the posts_join and posts_orderby filters –  Manny Fleurmond Jan 8 '11 at 6:32
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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