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.

I'm trying to create an advanced, reusable query function.

I need to query by category OR a category + a tag.

I know how to do this with custom fields (meta queries) but how do I do it with simple categories and tags?

A pseudo SQL Query would be:

Select * from Posts where ( cat_id = 1 OR (cat_id = 5 AND tag_id = 6) )

The query could change to need to include a set of tags

Select * from Posts where ( cat_id = 1 OR ( cat_id = 5 AND tag_id = (5,6,7) ))

Currently I'm using wp_query and passing args, but I guess I could write a one-off query_posts if needed.

Here is a rough version of my custom query. I'm guessing I need to add another argument for my desired 'or' statement?

$args = array(
     'post_type'            => $postType, //assume 'post'
     'cat'                  => $cat_id, //currently a single id
     'orderby'              => 'date',
     'post_status'          => 'publish',
    );

I got some help from Best practice for multiple queries on page

So now I need to add a tax_query, but here is where my query fails

$taxQuery = array(
       'relation' => 'AND',  //Is this "And" my original query, or just "and" these two parameters?            
                array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => 5
                ),
                array(
                    'taxonomy' => 'post_tag',
                    'field' => 'id',
                    'terms' => array(5,6,7)
                )
        );

My updated WP_query would be :

$args = array(
     'post_type'            => $postType, //assume 'post'
     'cat'                  => $cat_id, //currently a single id
     'tax_query'            => $taxQuery,
     'orderby'              => 'date',
     'post_status'          => 'publish',
    );

Thank you for your time!

share|improve this question

1 Answer 1

I am not 100% sure what you are asking but as written that is going to be wrong. tax_query is an array of arrays but you have an array of array of arrays. You create the third array when you put $taxQuery into array($taxQuery). This should be more correct:

$args = array(
     'post_type'            => $postType, //assume 'post'
     'cat'                  => $cat_id, //currently a single id
     'tax_query'            => $taxQuery,
     'orderby'              => 'date',
     'post_status'          => 'publish',
);

With your version, if you var_dump the query you can see 0=1 in the SQL which reflects the broken tax_query, and if you have debugging enabled you can see Notices.

Unfortunately, you can't do a complicated query like this one...

Select * from Posts where ( cat_id = 1 OR ( cat_id = 5 AND tag_id = (5,6,7) ))

... with WP_Query. The nested conditions in the WHERE are too complex for WP_Query.

You have several options:

  1. Write the SQL yourself
  2. Let WP_Query do part of the work and alter, at the very least, the WHERE clause with posts_where
  3. Run several queries to grab the data.

The latter would look something like:

$post_ids = new WP_Query(array(
  // query for one post type
  'fields' => 'ids',
  // other parameters
));

$post_ids_2 = new WP_Query(array(
  // query for the others
  'fields' => 'ids',
  // other parameters
));
// join them
$post_ids = $post_ids->posts + $post_ids_2->posts;
$posts_qry = new WP_Query(array('post__in'=> $posts_ids));

That is taken from another answer so none of the parameter are right for you but that should give you idea. That is by far the easiest solution but also the least efficient.

share|improve this answer
    
Thanks - you are correct - I had another function that was taking an array of arrays for an advanced date filter. Still, this doesn't answer the question. –  Nate Jul 3 '13 at 17:48
    
@Nate : see the edit –  s_ha_dum Jul 3 '13 at 18:15

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.