WP_Query: Filter tax_query OR meta_query

How can I combine the result of the tax_query and meta_query?

ex:
tax_query results to:
Post1, Post2.

Read More

and meta_query results to:
Post3.

I want to combine the results of the 2 queries.
Here is my partial code:

'tax_query' => array(
     'relation' => 'AND',
     array(
         'taxonomy' => 'tax1',
         'field'    => 'term_id',
         'terms'    => array(1,2,3),
     ),
     array(
         'taxonomy' => 'tax2',
         'field'    => 'term_id',
         'terms'    => array(1,2,3),
     ),
 ),
 'meta_query' => array(
     array(
         'key'     => 'meta1',
         'value'   => '1',
         'compare' => '=',
      ), 
 ),

The same question was asked here but wasn’t answered. So I’m re-opening it.
Thanks!

Related posts

Leave a Reply

2 comments

  1. It sounds like you are wanting it to act like an ‘OR’ where a post that matches either the tax_query or meta_query is returned.

    Unfortunately, that’s not possible using WP_Query.

    You’ll either need to write a custom database call, or just query them separately and do your checking on the PHP end (that’s ok if you know you’ll have a relatively small number of results, but be warned this won’t necessarily scale to a huge site).

  2. The only way to achieve a query like that is creating a custom query to the db using the $wpdb global and SQL statements. I think it would be something like this:

    global $wpdb;
    $querystr = 
    "
    SELECT * FROM $wpdb->posts
    LEFT JOIN $wpdb->postmeta ON ($wpdb->posts.ID = $wpdb->postmeta.post_id)
    LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
    LEFT JOIN $wpdb->term_taxonomy as term_taxonomy1 ON($wpdb->term_relationships.term_taxonomy_id = term_taxonomy1.term_taxonomy_id)
    LEFT JOIN $wpdb->term_taxonomy as term_taxonomy2 ON($wpdb->term_relationships.term_taxonomy_id = term_taxonomy2.term_taxonomy_id)
    LEFT JOIN $wpdb->terms as tax1_term1 ON(term_taxonomy1.term_id = tax1_term1.term_id)
    LEFT JOIN $wpdb->terms as tax1_term2 ON(term_taxonomy1.term_id = tax1_term2.term_id)
    LEFT JOIN $wpdb->terms as tax1_term3 ON(term_taxonomy1.term_id = tax1_term3.term_id)
    LEFT JOIN $wpdb->terms as tax2_term1 ON(term_taxonomy2.term_id = tax2_term1.term_id)
    LEFT JOIN $wpdb->terms as tax2_term2 ON(term_taxonomy2.term_id = tax2_term2.term_id)
    LEFT JOIN $wpdb->terms as tax2_term3 ON(term_taxonomy2.term_id = tax2_term3.term_id)
    WHERE 
    (
        (
            (term_taxonomy1.taxonomy = 'tax1') 
            AND 
            (tax1_term1.term_id = 1 AND tax1_term2.term_id = 2 AND tax1_term3.term_id = 3)
        )
        OR
        (
            (term_taxonomy2.taxonomy = 'tax2') 
            AND 
            (tax2_term1.term_id = 1 AND tax2_term2.term_id = 2 AND tax2_term3.term_id = 3)
        )
    )
    OR
    (
        $wpdb->postmeta.meta_key = 'meta1' AND $wpdb->postmeta.meta_value = '1'
    )
    ORDER BY $wpdb->postmeta.meta_value ASC
    "
    $pageposts = $wpdb->get_results($querystr, OBJECT);
    

    Then you could iterate over $pageposts as with a WP_Query loop.