Tricky WP Query

I am trying to use wp_query (or another native WordPress query class) to do the following:

get all posts WHERE
( post_type = ‘post’ AND category = 7 ) OR
( post_type = ‘case-studies’ AND meta_key = ‘homeslide’ AND meta_value = 1 )

Read More

I am not sure any of them can handle this yet.

Trying with WP Query:

$args = array (
    'relation' => 'OR',
    array(
        'meta_key' => '_homeslide', 
        'meta_value' => '1'
    ),
    array(
        'category' => '7'
    )
);

But I think “relation” is only for use with tax_query.

I could probably use $wpdb to create an advanced query but wanted to see if it could be done with the others and see if I was missing something obvious.

Related posts

Leave a Reply

2 comments

  1. For that kind of complex query, I’d recommend running two queries and then merging the results.

    First, get an array for:

    get all posts WHERE ( post_type = ‘post’ AND category = 7 )

    Then, get an array for:

    ( post_type = ‘case-studies’ AND meta_key = ‘homeslide’ AND meta_value = 1 )

    Then use array_merge() to combine the arrays and and you have a collection that satisfies your requirements. Yes, you’re doing to queries … but this seems like a fairly quick/easy short-term solution.

  2. Ok I put together a solution using get_posts & query_posts to return the arrays for each: posts and case-studies. Then array_merged them (thanks for the heads up EAMann), then using uasort() with a custom compare function to sort them by post_date.

    It’s not the most attractive solution, but since it works and I’m only returning a max of 5 posts in total from each query, it’ll do.

    // Collect posts
    $news = get_posts(); 
    $cs = query_posts( array(
        'post_type' => 'case-studies',
        'meta_key' => '_homeslide',
        'meta_value' => 'true'
    ));
    
    // Merge the two arrays
    $vslides = array_merge($news, $cs);
    
    // Function to compare array elements using post_date
    function compare($x, $y) {
        if ( strtotime($x->post_date) == strtotime($y->post_date) )
            return 0;
        else if ( strtotime($x->post_date) > strtotime($y->post_date) )
            return -1;
        else  
            return 1;
    }
    
    // Sort by post_date
    uasort($vslides, 'compare');