You can do it with a posts_where
filter and a subquery. Note that you have to explicitly set suppress_filters
to false, as get_posts
normally ignores filters:
function wpse28018_posts_where( $where ) {
global $wpdb;
$where .= " AND {$wpdb->posts}.ID NOT IN ( SELECT DISTINCT post_id FROM {$wpdb->postmeta} WHERE meta_key = 'alternate_page' )";
return $where;
}
// add the filter
add_filter( 'posts_where' , 'wpse28018_posts_where' );
// do the query
$articles = get_posts(array(
'post_parent' => 0,
'post_type' => 'custom_type',
'suppress_filters' => false
));
// remove the filter so other queries aren't affected.
remove_filter( 'posts_where' , 'wpse28018_posts_where' );