<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC', 'meta_key' => featured_product, 'meta_value' => 1)); ?>

<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC')); ?>

I have 2 queries, first to show meta key with featured_product eq 1. So I want to exclude all the featured products on the second query. How can i do that please? Thanks!

4 Answers 4


I've never had any luck getting the meta compare to work either--but I came up with a workaround for this exact situation (having "featured" items at the top of the page).

First, you probably shouldn't be using query_posts for both queries. You should use a custom query for at least the first one. Then, while you're running that loop, keep the ids of any "featured" posts in a variable. When you run your second loop, you can use the "post__not_in" arg to exclude the featured ones. Like so:

// Set up a custom query
$featured_query = new WP_query();

// Your query args

// Run it

    if ($featured_query->have_posts()) {

    while ($featured_query->have_posts()) {


        // Remember the featued ID
        $featured_post_id = get_the_ID(); 

        // Render your featured post here



// Set up the args for your main query
$args = array(
        'post_type' => 'post',
        'post__not_in' => array($featured_post_id) // Don't show the featured post

// Now run your main query and so on...
  • post__not_in is probably the only way to do this, if you want to include posts that have featured_product not set to 1, or not set at all (which is maybe why eileen's answer fails). Rarst also gave a good overview of query_posts() vs get_posts()
    – Jan Fabry
    Nov 12, 2010 at 18:33
  • Good workaround. Another possibility is using a category or tag for your featured category, rather than a custom field. Then you can use "cat__not_in" or "tag__not_in" in your query to exclude the featured posts. Nov 12, 2010 at 18:45
  • it has to be as a page item, so can't use cat or tag, thanks.
    – ray
    Nov 12, 2010 at 19:11
  • @ray: Have you tried calling register_taxonomy_for_object_type('category', 'page')? This should allow you to use categories for pages too. Use post_tag instead of category for tags.
    – Jan Fabry
    Nov 12, 2010 at 19:27

MathSmath's answer is ok, but it's very inefficient and would not scale to a WordPress site with 100,000+ posts or what have you. Doing a WP_Query() for 1000 posts is going to be slow enough.

Rather than using a posts_not_it (which would pass a query long string if you hade several thousand posts here) if you have MySQL 4.1+ it would be better to use a subquery to exclude the posts you don't want.

Here is a slightly modified example I am using on a site with 250,000+ posts.

// add a filter to 'posts_where' to add the subquery
add_filter( 'posts_where', '_exclude_meta_key_in_posts_where' );    

// make the query, the below function will be called
query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC'));

function _exclude_meta_key_in_posts_where( $where ) {

    global $wpdb;
    return $where . " AND $wpdb->posts.ID NOT IN ( SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = 'featured_product' AND meta_value > '' )";

//remove the filter incase we do any more query_posts()s
remove_filter( 'posts_where', '_exclude_meta_key_in_posts_where' );

You could probably do it all in one create_function() though I am not sure if that is very efficient, but would be less lines:

// add a filter to 'posts_where' to add the subquery
add_filter( 'posts_where', create_function( '$where', 'global $wpdb; return $where . " AND $wpdb->posts.ID NOT IN ( SELECT DISTINCT post_id FROM $wpdb->postmeta WHERE meta_key = \'featured_product\' AND meta_value > \'\' )";' ) );

I didn't test the create_function() example.


I haven't tried this, but some research let me to this. Using meta_compare you can check if meta_value does not equal 1 display the posts.

<?php query_posts(array('showposts' => 1000, 'post_parent' => $post->ID, 'post_type' => 'page', 'orderby' => 'title', 'order' => 'ASC', 'meta_value' => featured_product, 'meta_compare' => '!=', 'meta_value' => 1 )); ?>
  • Thanks for that, but it doesn't work to me. it won't show any posts on the second query
    – ray
    Nov 12, 2010 at 17:24
  • Did you reset the query after the first one? What about trying less than instead of !=? Nov 12, 2010 at 17:34
  • what do you mean 'less than' please? and wp_reset_query(); to reset right, yeah it was there.
    – ray
    Nov 12, 2010 at 17:39
  • yeah, i see what you mean <= or < I tried but no luck
    – ray
    Nov 12, 2010 at 17:44
  • Make sure that 'featured_product' is a string in quotes in the array. featured_product should be'featured_product'
    – kevtrout
    Nov 12, 2010 at 17:45

My solution was to add the custom field with a 'false' value to all of the existing posts and to hook the creation of new posts in order to add the field to them as well.

I'm not sure if this is a more efficient way to handle this situation but I wanted to stay away from custom SQL queries.

The following is a one-time-use function I used for adding the field to all existing posts:

function unfeature_all() {
    $args = array(
        'numberposts'   => -1,

    $posts = get_posts( $args );

    foreach ($posts as $post) {
        $status = get_post_meta($post->ID, 'featured_post', true);
        if (!$status) {
            update_post_meta($post->ID, 'featured_post', false);


if (current_user_can('manage_options')) unfeature_all();

Your Answer

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