Recently, for a client, I needed set up a custom WordPress query that fetched a number of posts by their id. Not hard I thought, after all there is a nice argument, post__in, where you simply pass it an array of post ids (not page ids) and the query returns you those posts. Except I was getting, not just posts I had chosen, but whole load of other random ones as well.
Doing a Google search for this phenomenon only brought up cases where people weren’t getting any results. This is most commonly due to people passing post__in a string rather than an array. If that’s the case, this is how you should set it up.
query_posts( array( 'post__in' => array(1, 2, 3) ) );
However, that wasn’t my problem and after wasting a lot of time trying to find out where my extra posts where coming from, it turns out they were ‘sticky’ posts. Post__in doesn’t automatically overrule everything that the query would normally return. So that you don’t get more results than you anticipated try using ‘ignore_sticky_posts’. It should like something like this:
query_posts( array( 'post__in' => array(1, 2, 3), 'ignore_sticky_posts' => true ) );