If you want to check out some nifty stuff, check out the NTILE function, which does something similar but a bit more elegantly. http://msdn.microsoft.com/en-us/library/ms175126(v=sql.105).aspx The only thing to keep in mind is that it may tile them into slightly unequal groups if the result of the division is not an integer.

Nothing that I am going to say below is actionable information - these are just thoughts:

If it were a readonly table, you could have pre-computed the flags and stored, in which case, you wouldn't even need a view.

Another thought is to have a computed column or persisted view, but computed columns don't work with row_number() functions, so that is a non-starter. If I am not mistaken, in a persisted view you cannot create a unique clustered index on a column that has a ranking function. So that is out as well.

You might be able to use some clever combination of TOP 20 PERCENT ... ORDER BY DATA ASC and TOP 20 PERCENT ... ORDER BY DATA DESC, but not clear to me what. Even then, the server will have to sort the data - which means it will need to read all the data.

An index on DATA column is a possibility that might help. If you have an index, it has statistics on the index, so SQL Server knows the distribution of the data; so theoretically that should help. But I haven't experimented with it to say whether or not it will.

To start off, I would keep the query as it as it is (or use a cte instead of a subquery, whichever you feel comfortable with) and make it into a view and see how the performance is.

The bottom line is, when you want to identify the top N percent based on a value, unless SQL Server has some statistical information to determine where to cut it off, it would have to examine every row of data.