• JP, the HAVING clause has no effect in this query, because the estimateddate is part of the GROUP BY clause (and the MIN function is evaluated for each group and, of course, each group has only one date).

    I think the query should be written like this:

    SELECT r.roofid, c1.estimatedcost as CapCost, c1.estimateddate
    FROM tblcapitalexpenditures c1
    INNER JOIN tblroofs r ON c1.RoofID = r.RoofID
    WHERE r.CompanyID = @CompanyID AND YEAR(cap.estimateddate)> YEAR(GETDATE())+1
    AND c1.estimateddate = (
     SELECT MIN(c2.estimateddate) FROM tblcapitalexpenditures c2
     WHERE c1.RoofID = c2.RoofID
    )

    I have replaced the outer join with an inner join because an outer join seems unnecessary to me. If it is really needed (if it is possible that a "roof" has no "capital expenditures" and you want that "roof" selected), the query would be:

    SELECT r.roofid, c1.estimatedcost as CapCost, c1.estimateddate
    FROM tblcapitalexpenditures c1
    RIGHT JOIN tblroofs r ON c1.RoofID = r.RoofID
    WHERE r.CompanyID = @CompanyID AND YEAR(cap.estimateddate)> YEAR(GETDATE())+1
    AND (c1.estimateddate IS NULL OR c1.estimateddate = (
     SELECT MIN(c2.estimateddate) FROM tblcapitalexpenditures c2
     WHERE c1.RoofID = c2.RoofID
    ))

    Razvan