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? Apr 24, 2014 at 16:21
  • 1
    Just do multiple queries, WP querying doesn't handle such type of logic.
    – Rarst
    Apr 24, 2014 at 16:23
  • @codearachnid custom query will also be ok, as long as it does not take much server load. Apr 24, 2014 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, 2014 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, 2014 at 18:34

2 Answers 2


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);
  • +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, 2016 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.

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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