As of writing, there is no meta query compare
value that can do what you’re trying to do, which is basically “where <updated_at meta> > <build_ran_at meta>“. But there are two options that you can choose from as an alternative to using the meta_query
arg:
-
Use a raw SQL to retrieve just the IDs of the posts having the
updated_at
meta greater than thebuild_ran_at
meta, and then pass the IDs toWP_Query
via thepost__in
arg like so:// Build the raw SQL. $query = " SELECT p.ID FROM $wpdb->posts p INNER JOIN $wpdb->postmeta pm ON pm.post_id = p.ID INNER JOIN $wpdb->postmeta pm2 ON pm2.post_id = p.ID WHERE p.post_type="foobar" AND p.post_status="publish" AND pm.meta_key = 'updated_at' AND pm2.meta_key = 'build_ran_at' AND pm.meta_value > pm2.meta_value LIMIT 999 "; // Get the post IDs. $ids = $wpdb->get_col( $query ); // Then use the IDs as the post__in value. $foobar_query = new WP_Query([ 'post_type' => 'foobar', 'post_status' => 'publish', 'posts_per_page' => 999, 'post__in' => $ids, ]);
-
Or use the
posts_clauses
hook to add the above two JOIN clauses and also the last three conditions in the WHERE clause.Example using (a closure and) a custom query arg named
_updated_at
as a flag indicating whether we should filter the posts query clauses or not, to avoid otherWP_Query
queries from being affected:// Add the filter. add_filter( 'posts_clauses', function ( $clauses, $query ) { if ( '> build_ran_at' === $query->get( '_updated_at' ) ) { global $wpdb; $pm = uniqid( 'pm_' ); // unique table alias $clauses['join'] .= " INNER JOIN $wpdb->postmeta $pm ON {$pm}.post_id = {$wpdb->posts}.ID"; $pm2 = uniqid( 'pm_' ); // unique table alias $clauses['join'] .= " INNER JOIN $wpdb->postmeta $pm2 ON {$pm2}.post_id = {$wpdb->posts}.ID"; $clauses['where'] .= " AND ( {$pm}.meta_key = 'updated_at' AND {$pm2}.meta_key = 'build_ran_at'" "AND {$pm}.meta_value > {$pm2}.meta_value )"; } return $clauses; }, 10, 2 ); // Then use the _updated_at arg in place of meta_query. $foobar_query = new WP_Query([ 'post_type' => 'foobar', 'post_status' => 'publish', 'posts_per_page' => 999, '_updated_at' => '> build_ran_at', ]);