As has already been pointed out, it's your quoting. However, instead of using double quotes "" as an alternate form of string encapsulation, I'd suggest that you use q{}
so that your sql is still single quoted:
my $stmt = q{SELECT DATE_FORMAT(completion_time, '%m') as 'month', COUNT(id) as 'total' FROM calls WHERE DATE_FORMAT(completion_time, '%Y') = ? GROUP BY DATE_FORMAT(completion_time, '%m')};
my $sth = database->prepare($stmt);
$sth->execute(params->{year});
This is a much better technique to fall back to. This is also true for double quoted strings by using qq{}
. It's fairly common to have mixed single and double quotes in an html string, so as long as your braces are balanced (which they will be 99% of the time), then this avoids having to switch back and forth.