HAVING filters the aggregates produced by the GROUP BY clause. (ie A sort of WHERE clause for aggregates.) eg
GROUP BY YourId
HAVING COUNT(*) > 5
GROUP BY YourId
HAVING SUM(Amount) > 10
Incidentally your example is not standard SQL as total_tracks does not exist until the SELECT clause which is logically evaluated after the HAVING clause
Yes. Logically SELECT is evaluated after HAVING so the alias does not yet exist when the HAVING clause is evaluated.
To use an alias a nested SELECT, using either a CTE or derived table, would be needed:
WITH TotalCTE
AS
(
SELECT AlbumId, COUNT(TrackId) AS total_tracks
FROM Tracks
GROUP BY AlbumId
)
SELECT AlbumId, total_tracks
FROM TotalCTE
WHERE total_tracks >= 12;
or
SELECT AlbumId, total_tracks
FROM
(
SELECT AlbumId, COUNT(TrackId) AS total_tracks
FROM Tracks
GROUP BY AlbumId
) D
WHERE total_tracks >= 12;