5

I am trying to combine two WordPress queries but it's not working as well as pagination.

I want to display today's all posts sorted by comment count and after that I want to display all posts (excluding today's post) sorted by comment count.

I believe these are the two queries to accomplish task separately. But how can I combines these so that new query lists today's posts first sorted by comment count and then rest of the posts sorted by comment count. And also with pagination.

<?php

  $today = getdate();

  $args1 = array(
    'post_type' => 'post',
    'orderby' => 'comment_count',
    'ignore_sticky_posts' => 1,
    'date_query' => array(
      array(
        'year'  => $today['year'],
        'month' => $today['mon'],
        'day'   => $today['mday'],
      ),
    ),
    'paged' => $paged,
  );

  $query1 = new WP_Query( $args1 );

  $args2 = array(
    'post_type' => 'post',
    'orderby' => 'comment_count',
    'ignore_sticky_posts' => 1,
    'paged' => $paged,
  );

  $query2 = new WP_Query( $args2 );

?>

EDIT: 1 //

@birgire, I tried the method you suggested. But got this mysql error.

WordPress database error: [You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '-5,5' at line 1]
SELECT SQL_CALC_FOUND_ROWS * FROM ( (SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND ( ( post_date > '2014-08-27 00:00:00' ) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.comment_count DESC LIMIT 1000) UNION ALL (SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND ( ( post_date < '2014-08-27 00:00:00' ) ) AND wp_posts.post_type = 'post' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.comment_count DESC LIMIT 1000 ) ) as combined LIMIT -5,5
  • I once experimented with combined queries here. – birgire Aug 27 '14 at 8:05
4

You can try the following (untested):

Setup the query arguments #1: (today)

  //-----------------
  // Query part #1:
  //-----------------
  $args1 = array(
     'post_type'           => 'post',
     'orderby'             => 'comment_count',
     'ignore_sticky_posts' => 1,
     'date_query'          => array(
          array(
              'after' => date('Y-m-d'),
          ),
         'inclusive'  => true,
      )
  );

Setup the query arguments #2: (!today)

  //-----------------
  // Query part #2:
  //-----------------
  $args2 = array(
      'post_type'           => 'post',
      'orderby'             => 'comment_count',
      'ignore_sticky_posts' => 1,
      'date_query'          => array(
          array(
              'before' => date('Y-m-d'),
          ),
         'inclusive'  => false,
      )
  );

Then we combine it:

//---------------------------
// Combined queries #1 + #2:
//---------------------------
$args = array( 
   'posts_per_page' => 5,
   'paged'          => ( $paged = get_query_var( 'paged' ) ) ? $paged : 1 ,
   'sublimit'       => 1000,
   'args'           => array( $args1, $args2 ),
);
$results = new WP_Combine_Queries( $args );

where we use the experimental WP_Combine_Queries class from here.

It's currently using UNION but you might want to use UNION ALL instead.

GitHub:

The plugin is now available on GitHub here.

  • Hi, I tried it but got mysql error. Please check edit in original post for. – Robert hue Aug 27 '14 at 12:29
  • Hi @Roberthue, I think you forgot to define $paged, so you're most likely feeding it with an empty string. Try for example the number 1 instead. Or check my update. – birgire Aug 27 '14 at 13:57
  • It's working now. :) Although I have a question about this method. Does it accepts all type of complex arguments defined in codex.wordpress.org/Class_Reference/WP_Query SO can I use more complex methods without any errors? And what is sublimit? Is it limiting total posts returned by query? – Robert hue Aug 27 '14 at 14:17
  • Great! Yes it should work with all WP_Query parameters in each sub query, but notice that the paramters posts_per_page and paged are overridden. The sublimit parameter is used as a trick to preserve the order of UNION sub queries (see the other post). I add it here so you can modify it to your needs. Just increase it if each subquery has more than 1000 posts. Note that this is experimental so every feedback is welcomed ;-) I will add this to GitHub soon. You might then want to play with UNION vs UNION ALL, in the SQL query, depending if you're using mutually exclusive sub queries. – birgire Aug 27 '14 at 15:15
  • Cool. :) Yes please put it on GitHub so others can report bugs. Although It's working fine and nothing big of a issue for me but there is a bug (kind of). This class sorts posts by arguments but the second sorting should be done by time and not post IDs. For eg, if 5 or 10 of my posts have some comment count then they are displayed by increasing post IDs, but it should list them newest to oldest. Do you understand what I am saying. But thanks man! I am accepting your answer. – Robert hue Aug 27 '14 at 16:03

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.