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?

  • 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 '14 at 16:21
  • 1
    Just do multiple queries, WP querying doesn't handle such type of logic. – Rarst Apr 24 '14 at 16:23
  • @codearachnid custom query will also be ok, as long as it does not take much server load. – тнє Sufi Apr 24 '14 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 '14 at 16:51
  • 1
    @StephenS. yes, however quite often it's not meaningful enough to waste time on hammering out (nearly) completely custom querying code – Rarst Apr 24 '14 at 18:34

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() {

    $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);
| improve this answer | |
  • +1 for the use of transient and updating on save_post, i was looking for something like that to improve performance. n1 – Larzan Feb 9 '16 at 11:16

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.

| improve this answer | |
  • It's certainly possible in a single query with raw SQL, via UNION. – Milo Apr 24 '14 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 '14 at 14:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.