When doing a sort on posts with a meta value, the way the SQL is currently generated in meta.php creates a condition where records that DO NOT have the queried meta value are excluded from the results.
A workaround (based on a Stack Exchange answer) that was helpful for me:
function sort_by_checkbox_value_19653( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
$query->set( 'meta_key', 'my_custom_field_name' );
$query->set( 'orderby', array( 'meta_value' => 'DESC', 'ID' => 'DESC' ) );
add_filter( 'get_meta_sql', 'filter_get_meta_sql_19653' );
}
add_action( 'pre_get_posts', 'sort_by_checkbox_value_19653' );
function filter_get_meta_sql_19653( $clauses ) {
remove_filter( 'get_meta_sql', 'filter_get_meta_sql_19653' );
// Change the inner join to a left join,
// and change the where so it is applied to the join, not the results of the query.
$clauses['join'] = str_replace( 'INNER JOIN', 'LEFT JOIN', $clauses['join'] ) . $clauses['where'];
$clauses['where'] = '';
return $clauses;
}