What result do you want returned, when Mangox is not found in the list? Did you want the query to not return a row?
There's no need for an ORDER BY clause, since the query returns one row. The "outerness" of the LEFT JOIN is negated by the predicate in the WHERE clause. (If info.description = something, that means that info.description IS NOT NULL, which means it will exclude any rows from items that didn't have a matching row from info. So, it's effectively an inner join.)
To return no row when the specified :itm does not exist in the items table, you can perform a join operation to a query that returns zero rows.
SELECT p.pos
FROM ( SELECT COUNT(*) AS pos
FROM items
JOIN info
ON items.refID = info.refID
WHERE info.description = :status
AND items.itmName < :itm
) p
CROSS
JOIN (SELECT 1
FROM items r
WHERE r.itmName = :itm2 -- additional bind placeholder
LIMIT 1
) q
You'd need to pass in the value of $itm a second time, for the added bind placeholder.
$stmt->execute(array(':status'=>"inStock", ':itm'=>$itm, ':itm2'=>$itm));
// ^^^^^^^^^^^^^^^
When there isn't a row returned, the fetch will return FALSE, so you'd need to to an additional check (that you actually got a row) before referencing $rslt[0].
$rslt = $stmt->fetch(PDO::FETCH_NUM);
if (!$rslt) {
// row returned
$pos = $rslt[0]+1;
} else {
// fetch failed, no row returned
// ??? do whatever you want to do when the exact word is not matched
$pos = 0; // ???
}
EDIT
The reason for the distinct bind placeholder name, :itm2, even when you're passing in the same value is that using the same bind placeholder name in a statement more than once (in PDO) doesn't work as we would expect, as it does with other database interfaces.