WordPress.org

Make WordPress Core

Opened 8 years ago

Closed 5 years ago

#4065 closed feature request (wontfix)

useful function: merge_wp_queries()

Reported by: markjaquith Owned by:
Milestone: Priority: low
Severity: minor Version:
Component: Optimization Keywords: needs-patch
Focuses: Cc:

Description

It would be really handy if you could take two WP_Query objects and merge them. Duplicate posts would be removed, and you could choose a sort column and sort order.

Example usage:

$q1 = new WP_Query('monthnum=12&year=2006');
$q2 = new WP_Query('monthnum=1&year=2007');
$merged = merge_wp_queries($q1, $q2, 'post_date_gmt', 'desc');

Change History (9)

comment:1 @darkdragon8 years ago

  • Component changed from Administration to Optimization
  • Milestone changed from 2.5 to 2.6

Bumping to 2.6 because of feature freeze and no patch.

comment:2 @darkdragon8 years ago

As an aside, this would be extremely useful, so I look forward to trying my hand on a patch for 2.6.

comment:3 @tomgf6 years ago

First step, combining the WHERE clause:

$q1 = new WP_Query('monthnum=10&year=2008');
$q2 = new WP_Query('monthnum=9&year=2008');
$merged = merge_wp_queries($q1, $q2, 'post_date_gmt', 'desc');

function merge_wp_queries( $q1, $q2, $sortby='post_date_gmt', $sortorder='desc' )
{
 global $wpdb, $merged_where;
 $where_1 = "( YEAR(".$wpdb->posts.".post_date)='".$q1->query_vars['year']."' AND MONTH(".$wpdb->posts.".post_date)='".$q1->query_vars['monthnum']."' )";
 $where_2 = "( YEAR(".$wpdb->posts.".post_date)='".$q2->query_vars['year']."' AND MONTH(".$wpdb->posts.".post_date)='".$q2->query_vars['monthnum']."' )";
 $merged_where = " AND ( $where_1 OR $where_2 )";
 
 add_filter('posts_where', 'merged_where' );
 return new WP_Query('showposts=10');
}

function merged_where( $where )
{
 global $merged_where;
 return $where . $merged_where;
}

comment:4 @Denis-de-Bernardy6 years ago

A better approach, imo, would be to change this:

function WP_Query ($query = '') {
	if (! empty($query)) {
		$this->query($query);
	}
}

into something like:

function WP_Query ($query = '') {
	$args = func_get_args();
	if (! empty($query) && count($args) == 1) {
		$this->query($query);
	} elseif ( count($args) > 1 ) {
		$this->union_query($query);
	}
}

that way, there is no need to actually merge the stuff in php. we'd union query the entire thing in one go. it requires subqueries, however, since the order by would need to apply to the fully unioned query passed as a subselect.

also, there are chances it would be *slow* (whichever way is used).

comment:5 @Denis-de-Bernardy6 years ago

$this->union_query($args); even

comment:6 @Denis-de-Bernardy6 years ago

  • Milestone changed from 2.9 to Future Release
  • Severity changed from normal to minor
  • Type changed from task (blessed) to feature request

comment:7 @ptahdunbar5 years ago

  • Cc trac@… added

comment:8 in reply to: ↑ description @mikeschinkel5 years ago

Replying to markjaquith:

It would be really handy if you could take two WP_Query objects and merge them. Duplicate posts would be removed, and you could choose a sort column and sort order.

Example usage:

$q1 = new WP_Query('monthnum=12&year=2006');
$q2 = new WP_Query('monthnum=1&year=2007');
$merged = merge_wp_queries($q1, $q2, 'post_date_gmt', 'desc');

Are you envisioning to merge the results after two queries are run, or merge the SQL and only run one query? Looks like the former but isn't that just an array merge?

comment:9 @markjaquith5 years ago

  • Milestone Future Release deleted
  • Resolution set to wontfix
  • Status changed from new to closed

I'm closing this. The new taxonomy and custom field options in WP_Query provide for just about everything I wanted here.

Note: See TracTickets for help on using tickets.