Support » Fixing WordPress » How can I filter posts belonging to 2 categories with query_posts()?

  • Resolved taote


    How can I get the posts that belong to 2 or more categories, (but not only one of them) with query_posts?

    If I use query_posts('cat=2,6'); it gives back all the posts that belongs at least to one of them, I need those belonging to both.

Viewing 15 replies - 1 through 15 (of 19 total)
  • Moderator Samuel Wood (Otto)

    (@otto42) Admin


    Otto42, I tried query_posts(array('category__and'=>'2,6')); and the query failed, but afterwards tried query_posts(array('category__and'=>array(2,6))); and it worked.

    Thank you very much, this should be documented.

    Otto42 & taote, thanks SO much.


    works perfectly. Any ideas on how to combine that with the other query_posts parameters, i.e. &showposts= and &order= ? I can’t figure out the syntax.




    That’s terrific MichaelH, thanks so much!

    On the same topic, only a little different…

    How can I filter subcategory posts from a category that has subcategories?

    For example, say I have a category that is hunting with the subcategories Big Game, Small Game, Waterfoul and Hunting Reports.

    Using the query_posts() how could I exclude the posts in the “hunting reports” category from the query?

    Similarly, if the Main Category, Hunting (that covered all the topics above), had only one subcategory that was “hunting reports” how would I exclude the posts from the single subcategory in the query?

    I’ve tried everything using exclude, hierarchy, etc. but all of them ended up listing the posts in the subcat…maybe my syntax was off but I’ve just had no luck and I’m pulling my hair out. I’ve spent three days searching google for something on this topic before finally arriving here!! Everything seems to be about wp_list_categories, which is not what I’m trying to do. I want to exclude posts from a category’s subcats.


    its not the syntax… if you include the parent category, query_posts doesn’t allow you to exclude the child of that parent.

    for this, you may need to use get_posts() instead of query_posts. If you specify a category with this function, it will not gather from children by default, so you will just have to specify all the children you want, as well.

    your alternative is to make a special category called “hidden” or something, which is outside the ‘hunting’ heirachy, and put all your ‘hunting reports’ posts into the ‘hidden’ category as well

    if you then exclude ‘hidden’ from query_posts, it will correctly exclude them, even though they’re also in the ‘hunting reports’ child category.

    Thanks for the help so far in this thread, very useful.

    I am having trouble with one thing, i am trying to get two sets of the latest posts that exist in categories 11,13,15,17,19,21 and then another loop that contains posts in cats: 12,14,16,18,20,22, but I ALSO want to ensure that all of the posts pulled are members of category 7 (7 is NOT the parent of the others).

    I was trying these two queries:

    query_posts(array('cat=11,13,15,17,19,21', 'category__and'=>array(7),'showposts'=>6,'orderby'=>menu_order,'order'=>ASC));
    query_posts(array('cat=12,14,16,18,20,22', 'category__and'=>array(7),'showposts'=>6,'orderby'=>menu_order,'order'=>ASC));

    but the results end up being identical. Any help you can offer is greatly appreciated, please?

    I know its not ideal, but you won’t really do a hell of a lot more processing by just looping through them all, and only outputting posts that are in category 7 based on a simple conditional.

    look up in_category() in the codex.

    what I mean is… as you go though the loop to output your posts, just skip over any that are not in cat7.

    Thanks for your quick response! I considered that, but was hesitant because i want to pull ONLY the most recent one from each category which is the reason for the limit of 6. I guess I could create a conditional loop:
    ie: (i=0, i++, if(i>6){[don't output]})

    but I am wondering how much extra load that is going to create when the page is getting hit thousands of times….do the results of a query like that get cached….?

    I don’t think the extra load would make very much difference really… but if load is a concern (and it should be) you should look into a plugin that caches your site properly – all of it, not just the queries.

    check out the WP Super Cache plugin.

    I’d like to go back to the top of this thread to clarify something. When you use this format:


    is it possible to replace one of the array values with a variable? I would like to get a list of posts that are in the current category (my variable) and another (static) category – but I have not yet found a way to do this.

    @brockangelo: You can just set up an array ouside the query_posts() function and use it as the value for category__and, like:

    $myarray = (1,2);

    At least that should work.

    Moderator Samuel Wood (Otto)

    (@otto42) Admin

    That should be:

    $myarray = array(1,2);

    Although brock’s question could be answered like this as well:


    For the record here’s a function that will let you spawn a fresh new query and add whatever arguments you want (in url var ($x=y) or array format. You can also tell it to use or ignore the existing query variables for the current view.

    // ---------------------------------
    // Replacement for query_posts.
    // Uses a new query object and takes extra arguments
    // ----------------------------------
    // $new_args - query stuff to add to $query_string, can be array or url style string
    // 	       see wp function wp_parse_args() for details
    // $ignore_existing_args - if set to true only the $new_args will be used.
    function gv_query_posts($new_args = '', $ignore_existing_args = FALSE) {
    	global $query_string ;
    	// Set up $query_string as an array unless the ignore flag is set
    	if (!$ignore_existing_args)	$existing_args = wp_parse_args($query_string);
    	// Mix together new and existing args (new_args can be string or array)
     	$args = wp_parse_args( $new_args, $existing_args );
     	// Make sure there are no duplicates
    	extract( $args, EXTR_SKIP );
    	$posts = new wp_query($args);
    	return $posts;
    } // gv_query_posts
Viewing 15 replies - 1 through 15 (of 19 total)
  • The topic ‘How can I filter posts belonging to 2 categories with query_posts()?’ is closed to new replies.