How to display max. 2 sticky posts when posts_per_page is 3?

Edit 2: Updated Code to account for “Maybe there are no stickied posts” 😉

Edit: I did a boo-boo with the number of posts. Fixed, should work now as intended.

You can do this by using two queries.

<?php
//First, you get all the sticky posts
$stickies = get_option('sticky_posts',array());
//then, get max 2 of them
$stickiessliced =array_slice($stickies,0,2); 
$numposts = 3 - count($stickiessliced);
//$numposts is now the number of remaining "normal" posts to be queried
if(count($stickiessliced)){
    //only query the stickies if there are some
    $sticky_loop = array(
        'posts_per_page' => count($stickiessliced),
        'orderby' => 'date',
        'post__in' => $stickiessliced,
        'ignore_sticky_posts' => true
    );
    //only get sliced sticky posts, ignore everything else
    $query = new WP_Query($sticky_loop);
    //do the loop for the sticky posts
    if ($query->have_posts()): ?>
         <?php while ($query->have_posts()): $query->the_post();?>

    // loop

         <?php endwhile;?>
         <?php wp_reset_query();?>
    <?php endif;
}
//now get the remaining posts to fill up to three
$main_loop = array(
    'posts_per_page' => $numposts,
    'orderby' => 'date',
    'post__not_in' => $stickies,
    //replace $stickiessliced with $stickies to make sure that NO other stickies are queried (as is: the above queried stickies are ignored)
    'ignore_sticky_posts' => true
);
$query = new WP_Query($main_loop);
//do the loop for the remaining posts to fill up
if ($query->have_posts()): ?>
     <?php while ($query->have_posts()): $query->the_post();?>

// loop

     <?php endwhile;?>
     <?php wp_reset_query();?>
<?php endif;
?>

This should work like this: if there are 0 to 2 sticky posts, they are queried, looped and then 1 to 3 “normal” posts are queried. If there are more than 2 sticky posts, the first 2 are sliced and then 1 more “normal” post is queried.

Happy Coding!