17

I have a customer transaction table. I need to create a query that includes a serial number pseudo column. The serial number should be automatically reset and start over from 1 upon change in customer ID.

Now, I am familiar with the row_number() function in SQL. This doesnt exactly solve my problem because to the best of my knowledge the serial number will not be reset in case the order of the rows change.

I want to do this in a single query (SQL Server) and without having to go through any temporary table usage etc. How can this be done?

2
  • 1
    The ROW_NUMBER() ranking function also has the ability to partition your data - check out the PARTITION BY clause in the OVER(.....) section of ROW_NUMBER() Commented Mar 23, 2011 at 6:32
  • is all sql server edition is supported? Commented Nov 8, 2021 at 11:37

9 Answers 9

30

Sometime we might don't want to apply ordering on our result set to add serial number. But if we are going to use ROW_NUMBER() then we have to have a ORDER BY clause. So, for that we can simply apply a tricks to avoid any ordering on the result set.

SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS ItemNo, ItemName FROM ItemMastetr

For that we don't need to apply order by on our result set. We'll just add ItemNo on our given result set.

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

Comments

17
select 
  ROW_NUMBER() Over (Order by CustomerID) As [S.N.], 
  CustomerID , 
  CustomerName, 
  Address, 
  City, 
  State, 
  ZipCode  
from Customers;

1 Comment

What is the meaning of "rep whoring!". Do you think it is good to write such remarks on a public forum by an educated person like you?
11

I'm not certain, based on your question if you want numbered rows that will remember their numbers even if the underlying data changes (and gives a different ordering), but if you just want numbered rows - that reset on a change in customer ID, then try using the Partition by clause of row_number()

row_number() over(partition by CustomerID order by CustomerID)

3 Comments

Being nitpicky - I believe the correct syntax would be: row_number() over(partition by CustomerID order by CustomerID) - the PARTITION BY needs to come first, and as far as I know, there's no comma between the partition and order by clauses
@marc_s I'll take your word for it - been a few months since I had to do a lot of SQL. Thanks for the correction.
You can always verify it on MSDN Books Online :-)
6

Implementing Serial Numbers Without Ordering Any of the Columns

enter image description here

Demo SQL Script-

IF OBJECT_ID('Tempdb..#TestTable') IS NOT NULL
    DROP TABLE #TestTable;

CREATE TABLE #TestTable (Names VARCHAR(75), Random_No INT); 

INSERT INTO #TestTable (Names,Random_No) VALUES
 ('Animal', 363)
,('Bat', 847)
,('Cat', 655)
,('Duet', 356)
,('Eagle', 136)
,('Frog', 784)
,('Ginger', 690); 

SELECT * FROM #TestTable;

There are ‘N’ methods for implementing Serial Numbers in SQL Server. Hereby, We have mentioned the Simple Row_Number Function to generate Serial Numbers.

ROW_NUMBER() Function is one of the Window Functions that numbers all rows sequentially (for example 1, 2, 3, …) It is a temporary value that will be calculated when the query is run. It must have an OVER Clause with ORDER BY. So, we cannot able to omit Order By Clause Simply. But we can use like below-

SQL Script

IF OBJECT_ID('Tempdb..#TestTable') IS NOT NULL
    DROP TABLE #TestTable;

CREATE TABLE #TestTable (Names VARCHAR(75), Random_No INT); 

INSERT INTO #TestTable (Names,Random_No) VALUES
 ('Animal', 363)
,('Bat', 847)
,('Cat', 655)
,('Duet', 356)
,('Eagle', 136)
,('Frog', 784)
,('Ginger', 690); 

SELECT Names,Random_No,ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS SERIAL_NO FROM #TestTable;

In the Above Query, We can Also Use SELECT 1, SELECT ‘ABC’, SELECT ” Instead of SELECT NULL. The result would be Same.

Comments

3
SELECT ROW_NUMBER()  OVER (ORDER BY  ColumnName1) As SrNo, ColumnName1,  ColumnName2 FROM  TableName

1 Comment

You should explain your SQL snippet. :)
1
select ROW_NUMBER() over (order by pk_field ) as srno 
from TableName

Comments

1

Using Common Table Expression (CTE)

WITH CTE AS(
    SELECT ROW_NUMBER() OVER(ORDER BY CustomerId) AS RowNumber,
    Customers.*
    FROM Customers
)
SELECT * FROM CTE

Comments

0

I found one solution for MYSQL its easy to add new column for SrNo or kind of tepropery auto increment column by following this query:

SELECT @ab:=@ab+1 as SrNo, tablename.* FROM tablename, (SELECT @ab:= 0)
AS ab

Comments

0
ALTER function dbo.FN_ReturnNumberRows(@Start int, @End int) returns @Numbers table (Number int) as
begin
    insert into @Numbers
    select n = ROW_NUMBER() OVER (ORDER BY n)+@Start-1 from (
    select top (@End-@Start+1) 1 as n from information_schema.columns as A
        cross join information_schema.columns as B
        cross join information_schema.columns as C
        cross join information_schema.columns as D
        cross join information_schema.columns as E) X
    return
end
GO

select * from dbo.FN_ReturnNumberRows(10,9999)

Comments

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.