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 have 5 different custom post types. I am showing 15 latest post from them on my home page using following query:

$query = new WP_Query( array (
             'posts_per_page'   => 15,
             'post_type' => array ( 'cpt1', 'cpt2', 'cpt3', 'cpt4', 'cpt5' ) 
          )
 );

It works fine, shows latest 15 posts from these 5 custom post types. But problem is, there are too many updates on cpt1 and cpt3 (around 8-10 posts per day on each post type). So on home page, I rarely find posts from cpt2/4/5.

So I want to show latest 3 posts from each post type (total 15 posts) using date as order by (sorting). So 3 posts from each post type will be visible and sorted based on date among all 5 post types. But I could not find any good solution for this.

What came so far in my mind is, running 5 queries and saving them to an array, and then sort them.

Is there anyway I can do this using only one query, instead of 5 queries?

share|improve this question
    
when you mean one query - are you trying to do this with WP_Query out of the box or are you fine with custom SQL? –  codearachnid Apr 24 at 16:21
1  
Just do multiple queries, WP querying doesn't handle such type of logic. –  Rarst Apr 24 at 16:23
    
@codearachnid custom query will also be ok, as long as it does not take much server load. –  тнє Sufi Apr 24 at 16:43
    
I have written several related answers, the most relevant is probably this one which includes links to a couple of others. –  s_ha_dum Apr 24 at 16:51
    
@Rarst yes, I couldn't find any option with WP query. I can do this with 5 WP queries, but I am concerned about the performance, since it will take quiet much load. –  тнє Sufi Apr 24 at 17:02

2 Answers 2

There is no way to do this in a single query. You must separate it out into multiple queries as SQL commands are not built to handle this type of processing, and thus neither is WordPress's Query API.

share|improve this answer
    
It's certainly possible in a single query with raw SQL, via UNION. –  Milo Apr 24 at 19:33
    
And I provided a link, in comments to the question, that demonstrates how to do it with WP_Query. It absolutely is possible in a single query if you are good enough with filters and SQL. –  s_ha_dum May 5 at 14:59
up vote 0 down vote accepted

I am not sure, if this is the most efficient option or not, but I have doen it in following way:

  1. I have stored 5 separate query using get_posts and stored them in a single array
  2. I had to flatten the array, since it was multidimensional. Then used usort using post_date to get the latest post
  3. I have saved this sorted data using Transient API, to minimize database call.

Here is the code:

function delete_front_page_query_results() {
    delete_transient('post_data');

    $query_cpt1 = array (
            'posts_per_page'   => 3,
            'post_type' => 'cpt1'
            );
    $query_cpt2 = array (
            'posts_per_page'   => 3,
            'post_type' => 'cpt2'
            );
    $query_cpt3 = array (
            'posts_per_page'   => 3,
            'post_type' => 'cpt3'
            );
    $query_cpt4 = array (
            'posts_per_page'   => 3,
            'post_type' => 'cpt4'
            );
    $query_cpt5 = array (
            'posts_per_page'   => 3,
            'post_type' => 'cpt5'
            );

    $query_results[] = get_posts($query_cpt1);
    $query_results[] = get_posts($query_cpt2);
    $query_results[] = get_posts($query_cpt3);
    $query_results[] = get_posts($query_cpt4);
    $query_results[] = get_posts($query_cpt5);

    //flattening three dimentional array to two dimensonal array
    $flatten_array =array();
    foreach ($query_results as $data) {
            foreach($data as $flatten_data) {
                 $flatten_array[] = $flatten_data;
            }
    }

    function cpt_array_sort($a, $b) {
            return strtotime($b->post_date) - strtotime($a->post_date);
    }
    usort($flatten_array, 'cpt_array_sort');

    //setting transient with the array
    set_transient ( 'post_data', $flatten_array, 365*24*60*60);
}
add_action('publish_post', 'delete_front_page_query_results);
share|improve this answer

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.