Here is a quick suggestion, should result in more consistent plan (for better or worse)
😎
CREATE PROCEDURE [Quotation].[Get_Quotes_LH] ( @From DateTime = null, @To DateTime = null )
AS
BEGIN
SELECT @From = COALESCE(@From, Min(QuotationDate)),
@To = COALESCE(@To , Max(QuotationDate))
FROM dbo.Quotation;
DECLARE @F_Loc DateTime = @From,
@T_Loc DateTime = @To;
DECLARE @CutOffDate DateTime = DATEADD(MONTH, -3, CURRENT_TIMESTAMP);
WITH QU_Memo(Quotation_Id, R, Next_Follow_Up) AS (
SELECT Quotation_Id,
ROW_NUMBER() OVER (PARTITION BY Quotation_Id ORDER BY Id DESC),
Next_Follow_Up
FROM Quotation.Follow_Up
)
SELECT QU.QuotationId,
COALESCE(QUIC.Next_Follow_Up, 0)
FROM dbo.Quotation QU
OUTER APPLY QU_Memo QUIC
WHERE QUICK.R = 1
AND QU.QuotationId = QUIC.Quotation_Id
AND (QU.QuotationDate > @F_Loc OR COALESCE(QUIC.Next_Follow_Up, 0) > 0 )
AND QU.QuotationDate <= @T_Loc
ORDER BY QU.QuotationId DESC;
END
GO
--#########################
EXEC [Quotation].[Get_Quotes_LH]