The join isn't that complex, but I wouldn't bother with it. Since you have a lot to remove a direct SQL query will run a LOT faster than WP.
However, we do need to keep track of the post ID numbers and remove the descendants and metadata.
Not tested / Make a backup / your risk etc. etc.
create temporary table `cull` (`post` int);
insert into cull select ID from wp_posts where my_criteria = 'my value';
delete from wp_posts where ID in ( select post from cull );
delete from wp_posts where post_parent in ( select post from cull );
-- done with temp table, cleanup metadata
delete from wp_postmeta where post_id not in ( select ID from wp_posts );
delete from wp_comments where comment_post_id not in ( select ID from wp_posts );
delete from wp_commentmeta where comment_id not in ( select comment_ID from wp_comments );
delete from wp_term_relationships where object_id not in ( select ID from wp_posts );