93

I have a simple select statement. I want to add a temporary column that will represent number the of rows in my result set. I tried this -

declare @num int
set @num = 0;
select t.A, t.B, t.C, (@count + 1) as number
from tableZ as t

It assigns the 1 to all rows. I tried @count = @count + 1 and it did not work. How do I do this thing in a simple manner?

thanks.

4
  • 1
    How do you want the row number to increment? Arbitrary? Your query doesn't have an ORDER BY, so, you need to define what you expect the ordering to be. Commented Nov 27, 2013 at 2:11
  • 1
    @AaronBertrand - I only need my rows to be numbered. Order is not really necessary. Does that answer your question ? Commented Nov 27, 2013 at 2:12
  • 1
    So you're okay with the order being applied randomly, and the results being spit out to your query in an inconsistent order every time? Commented Nov 27, 2013 at 2:14
  • stackoverflow.com/questions/26160970/… Commented Jun 27, 2022 at 17:34

2 Answers 2

138
SELECT
    t.A,
    t.B,
    t.C,
    ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS number
FROM tableZ AS t

See working example at SQLFiddle

Of course, you may want to define the row-numbering order – if so, just swap OVER (ORDER BY (SELECT 1)) for, e.g., OVER (ORDER BY t.C), like in a normal ORDER BY clause.

Sign up to request clarification or add additional context in comments.

3 Comments

Why does adding where number = 1 or some other where clause based of number throw an invalid column error? Is there any way to add a where clause based on the number column?
@CJEdgerton Because of the way a SELECT statement is parsed/read. The WHERE clause is calculated before aliases in the SELECT list are materialized. So to work around it you can just put the SELECT in a CTE/subquery and then use a where clause when selecting from that.
this information was helpful
89

The typical pattern would be as follows, but you need to actually define how the ordering should be applied (since a table is, by definition, an unordered bag of rows). One way to do that if you don't care about a specific order otherwise is to use the leading key(s) of a covering index, the leading key(s) of the clustered index, or the columns in any group by / order by clauses. In this case I'll assume A is the single-column clustering key for t:

SELECT t.A, t.B, t.C, number = ROW_NUMBER() OVER (ORDER BY t.A)
  FROM dbo.tableZ AS t
  ORDER BY t.A;

If you truly don't care about order, you can generate arbitrary/nondeterministic row numbering using:

ROW_NUMBER() OVER (ORDER BY @@SPID)

-- or for serial plans

ROW_NUMBER() OVER (ORDER BY @@TRANCOUNT)

Little tricks I picked up from Paul White in this article (see "Paul's Solution").

Not sure what the variables in your question are supposed to represent (they don't match).

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.