Using the result of a 'previous' column in a SELECT statement

This is actually covered as a warning in Variables (Transact-SQL):


If there are multiple assignment clauses in a single SELECT statement, SQL Server does not guarantee the order of evaluation of the expressions. Note that effects are only visible if there are references among the assignments.

(Emphasis mine)

SQL server does assign the values one variable at a time, so in this (simple) example, SQL Server has assigned the value of @a prior to evaluating (and assigning) the expression @a * 3 to @b.

As the warning says though, don't expect the behaviour to always be the same. If you need to guarantee that assignment is in a strict order, do the assignments as separate statements:

DECLARE @a int,
        @b int;
SET @a = 2;
SET @b  = @a * 3;
SELECT @a, @b;

Edit: This behaviour does not exist when using expressions that are not assignments. For example the following statement will fail with the error "Invalid column name 'a'.":

       a * 3 AS b;

The behaviour you are describing only happens for assignment statements. You cannot reference a column by it's alias in the same SELECT it was defined.