I think a HAVING clause is far less of a hack than a SELECT * FROM subselect.
Again, WHERE clauses are meant to directly limit the records to be selected. WHERE clauses do not need to drive indexes, but they do if they exist. If you need to filter on calculated values, you may need to do so in a HAVING clause.
That said, a WHERE clause (if possible) is preferable because more optimization is possible.
An example:
Suppose you have a table with coordinates (X and Y) and you want all the records within a radius R of a given point Xgiven, Ygiven. You could do so in a HAVING clause:
Code:
SELECT * FROM Coordinates
HAVING (X-Xgiven)*(X-Xgiven) + (Y-Ygiven)*(Y-Ygiven) < R*R;
But this can only be solved by going over every row, regardless of any indexes for the X and Y columns.
A better query would be:
Code:
SELECT * FROM Coordinates
WHERE X BETWEEN Xgiven-R AND Xgiven + R
AND Y BETWEEN Ygiven-R AND Ygiven + R
HAVING (X-Xgiven)*(X-Xgiven) + (Y-Ygiven)*(Y-Ygiven) < R*R;
What is the difference? Not the outcome. That should be the same. But the amount of rows to be checked is now reduced as the indexes on the X and/or Y column can be used to keep the really far records out of the calculation. So the difference in speed can be enormous.
+++ Despite being wrong in every important aspect, that is a very good analogy +++
Hex (in Darwin's Watch)