You can use filters to modify the SQL. I added something unique in the post_type so I could filter only this query and not change anything else.
The query for example
$query = new WP_Query(array('post_type'=>'something_unique_for_filter'));
And the filter
function custom_where($where, $query) {
global $wpdb;
if(false !== strpos($where, 'something_unique_for_filter')) {
$where = " AND post_type='page' AND post_parent != 0 AND ID IN (SELECT DISTINCT post_parent FROM $wpdb->posts WHERE post_type='page')";
}
return $where;
}
add_filter('posts_where', 'custom_where', 10, 2);
To add support for meta query first step is to add meta_key
to the WP_Query
so it INNER JOIN the postmeta table.
$query = new WP_Query(array('post_type'=>'something_unique_for_filter', 'meta_key'=>'something'));
And the filter with meta
function custom_where($where, $query) {
global $wpdb;
if(false !== strpos($where, 'something_unique_for_filter')) {
$where = " AND ( $wpdb->postmeta.meta_key = 'test' AND $wpdb->postmeta.meta_value = '123' )
AND post_type='page' AND post_parent != 0
AND ID IN (SELECT DISTINCT post_parent FROM $wpdb->posts WHERE post_type='page')";
}
return $where;
}
add_filter('posts_where', 'custom_where', 10, 2);