Мне нравится COALESCE.
Вам просто нужно быть осторожным с нулевыми значениями в левой части, если в левой части могут быть нулевые значения, вы можете сделать что-то вроде последней строки, чтобы нулевые значения совпадали. Как правило, с чем-то вроде этого, хотя вы хотите убедиться, что ваш запрос по-прежнему работает нормально.
SELECT idcallhistory3, callid, starttime, answertime, endtime, duration,
is_answ, is_fail, is_compl, is_fromoutside, mediatype, from_no,
to_no, callerid, dialednumber, lastcallerid, lastdialednumber,
group_no, line_no
FROM "public".callhistory3
WHERE (starttime >= COALESCE(@starttime, starttime ))
AND (endtime <= COALESCE(@endtime, endtime))
AND (is_fromoutside = COALESCE(@is_fromoutside, is_fromoutside))
AND (from_no = COALESCE(@from_no, from_no))
AND (COALESCE(to_no, -1) = COALESCE(@to_no, to_no, -1)) -- make nulls match