Question: I am curious whether Wordpress is able to run nested `meta_query`, with each having different relation keys? As of Wordpress 3.0, `tax_query` is able to perform this function; I'm wondering whether this has an equivalent with `meta_query`.

```
$results = query_posts( array(
    'post_type' => 'event_id',
    'meta_query' => array(
        'relation' => 'AND',
        array(
            'relation' => 'OR',
            array(
                'key' => 'primary_user_id',
                'value' => $user_id
            ),
            array(
                'key' => 'secondary_user_id',
                'value' => $user_id
            )
        ),
        array(
            'key' => 'date',
            'value' => array( $start_date, $end_date ),
            'type' => 'DATETIME',
            'compare' => 'BETWEEN'
        )
    )
) );

```

References:

* [WP\_Query Custom Field Parameters - Multiple Custom Field Handling](http://codex.wordpress.org/Class_Reference/WP_Query#Custom_Field_Parameters)
* [query multiple taxonomy and show post count](https://wordpress.stackexchange.com/questions/23995/query-multiple-taxonomy-and-show-post-count)
* [How navigation works in custom loop within shortcode?](https://wordpress.stackexchange.com/questions/70010/how-navigation-works-in-custom-loop-within-shortcode)

Answer: 
The question was for Wordpress 3.0, but just in case someone has the same question for a more recent version, from Wordpress Codex:

> 
> "Starting with version 4.1, meta\_query clauses can be nested in order to construct complex queries."
> 
> 
> 

<https://developer.wordpress.org/reference/classes/wp_query/#custom-field-post-meta-parameters>
So, that query should work on the current Wordpress version.
That seems to be impossible. Please someone correct me if I'm wrong.

The `meta_query` parameter will actually be transformed into a `WP_Meta_Query` object, and the `relation` verification won't go deeper in [`wp-includes/meta.php`](http://core.trac.wordpress.org/browser/trunk/wp-includes/meta.php#L647), and occurs just once in the top level:

```
if ( isset( $meta_query['relation'] ) && strtoupper( $meta_query['relation'] ) == 'OR' ) {
    $this->relation = 'OR';
} else {
    $this->relation = 'AND';
}

```

A possible solution for this is to build your own JOIN for this query.

```
$query = new WP_Query( array(
    ...
    'my_meta_query' => true,
    'suppress_filters' => false
) );

add_filter( 'posts_join', 'my_meta_query_posts_join', 10, 2 );
function my_meta_query_posts_join( $join, $query ) {

    if ( empty( $query->query_vars['my_meta_query'] ) )
        return $join;

    global $wpdb;

    $new_join = "
        INNER JOIN {$wpdb->postmeta} pm1 ON 1=1
            AND pm1.post_id = {$wpdb->posts}.ID
            AND pm1.meta_key = '_some_meta_key'
            AND pm1.meta_value = 'some_value'
    ";

    return $join . ' ' . $new_join;
}

```

And if you need further verifications and rules, you can also use the `posts_where` filter.