A few things, some nitpicks, some UX, some probably-bugs. What Lyle's Mug has already stated is also part of my answer, but first things first:
UX
This query is quite unwieldy to use, because all the things you might want to play with are hardcoded.
SEDE allows using parameters, with a rather simple syntax:
##name:type[?if optional, default value]##
replacing all your magic numbers gets us to:
SELECT TOP ##x:int?150##
-- ...
WHERE User.Age IS NOT NULL AND Users.Reputation > ##minrep:int?150## AND User.Age <= ##age:int?30##
Nitpicks:
Note that this already stretches out that single-line WHERE
quite much. I really like queries to state WHERE conditions on separate lines, because that makes it easier to process them.
Additionally I strongly recommend a lightly different comma-placement when listing columns, namely the comma before the declaration.
This has the advantage of allowing removals without running into syntax errors each time.
Probably-Bugs:
The ordering you Limit By is ... skewed? strange? ... well you select the youngest users and limit according to age, when the purpose of such a query is most probably reputation based stats.
Off-By-One: WHERE Rep > 150
excludes users with 150 rep!
Then again it seems that the where clause about rep is moot anyways...
If you remove it, there's a way to cut away large parts of "inactive" userbase depending on reputation. Usually when querying that table, I explicitly exclude users with 1 and 101 rep. These two values are a strong indicator for non-activity.
My final version:
SELECT TOP ##x:int?150##
ROW_NUMBER() OVER (ORDER BY Users.Reputation DESC) AS Rank
, Users.Id as [User Link]
, Users.Age
, Users.Reputation as Rep
FROM Users
WHERE Users.Age <= ##age:int?30##
ORDER BY Rank ASC;
(also available on SEDE)