Best Practice For Querying Grandchildren?

You’re on the right track. You can do this with just one MySQL query instead of two by joining on the post_parent. Drop this function into your functions.php file, then in your template you can replace your WP_Query call with $results = wpse_84810_get_grandchildren();, change your if clause to be if( $results && $results->have_posts() ), then carry on with the rest of your template code.

function wpse_84810_get_grandchildren( $grandparent_id = false ) {
    global $wpdb;

    if ( !$grandparent_id )
        $grandparent_id = get_the_ID();

    $grandchildren_ids = $wpdb->get_col( $wpdb->prepare( "SELECT p1.ID FROM {$wpdb->posts} AS p1 INNER JOIN {$wpdb->posts} AS p2 ON p1.post_parent = p2.ID WHERE p2.post_parent = %d", $grandparent_id ) );

    if ( $grandchildren_ids ) {
        return new WP_Query( array(
            'post__in' => $grandchildren_ids,
            'post_type' => 'page',
            'post_status' => 'publish',
            'posts_per_page' => 5,
            'paged' => get_query_var( 'paged' ) ? get_query_var( 'paged' ) : 1
        ) );
    }

    return false;
}

Leave a Comment