ROW_NUMBER
ROW_NUMBER ( )
OVER ( [ PARTITION BY value_expression ,
... [ n ] ] order_by_clause )
To add a row number column in front of each
row, add a column with the
ROW_NUMBER function, in
this case named Row#. You must move the ORDER BY clause up to the OVER clause.
SELECT
ROW_NUMBER() OVER(ORDER BY name ASC) AS Row#,
name, recovery_model_desc
FROM sys.databases
WHERE database_id < 5;
Adding a
PARTITION BY clause on the recovery_model_desc column, will restart the numbering when the recovery_model_desc value changes.
SELECT
ROW_NUMBER() OVER(PARTITION BY
recovery_model_desc ORDER BY name ASC)
AS Row#,
name, recovery_model_desc
FROM sys.databases WHERE database_id < 5;
Returning
The Row Number For Salespeople
USE AdventureWorks2012;
GO
SELECT ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS Row,
FirstName, LastName, ROUND(SalesYTD,2,1) AS "Sales
YTD"
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0;
Row FirstName LastName SalesYTD
--- ----------- ---------------------- -----------------
1 Linda
Mitchell
4251368.54
2 Jae
Pak
4116871.22
3 Michael
Blythe
3763178.17
4 Jillian
Carson
3189418.36
5 Ranjit
Varkey Chudukatil
3121616.32
6 José
Saraiva
2604540.71
7 Shu
Ito
2458535.61
8 Tsvi
Reiter
2315185.61
9 Rachel
Valdez 1827066.71
10 Tete
Mensa-Annan
1576562.19
11 David
Campbell
1573012.93
12 Garrett
Vargas
1453719.46
13 Lynn
Tsoflias
1421810.92
14 Pamela
Ansman-Wolfe 1352577.13
Returning A Subset Of Rows
Calculates row numbers for all rows in the
SalesOrderHeader table in the order of the OrderDate and returns only rows 50 to 60 inclusive.
USE AdventureWorks2012;
GO
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY
OrderDate) AS RowNumber
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN 50 AND 60;
Using ROW_NUMBER() with PARTITION
uses the
PARTITION BY argument to partition the query result set by the
column TerritoryName. The ORDER BY clause specified in the OVER clause orders the rows in each partition by the column SalesYTD. The ORDER BY clause in the SELECT statement orders the entire query result set by TerritoryName.
USE AdventureWorks2012;
GO
SELECT FirstName, LastName, TerritoryName, ROUND(SalesYTD,2,1) AS SalesYTD,
ROW_NUMBER() OVER(PARTITION BY
TerritoryName ORDER BY SalesYTD DESC)
AS Row
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0
ORDER BY TerritoryName;
FirstName LastName TerritoryName SalesYTD Row
--------- -------------------- ------------------ ------------
---
Lynn Tsoflias Australia 1421810.92 1
José Saraiva Canada 2604540.71 1
Garrett Vargas
Canada 1453719.46 2
Jillian Carson Central 3189418.36 1
Ranjit Varkey Chudukatil France 3121616.32 1
Rachel Valdez Germany 1827066.71 1
Michael Blythe Northeast 3763178.17 1
Tete Mensa-Annan Northwest 1576562.19 1
David Campbell Northwest 1573012.93 2
Pamela Ansman-Wolfe Northwest 1352577.13 3
Tsvi Reiter Southeast 2315185.61 1
Linda Mitchell Southwest 4251368.54 1
Shu Ito Southwest 2458535.61 2
Jae Pak United Kingdom 4116871.22 1
Returning The Row Number For Salespeople
returns the
ROW_NUMBER for sales representatives based on their assigned sales
quota.
-- Uses AdventureWorks
SELECT ROW_NUMBER() OVER(ORDER BY SUM(SalesAmountQuota) DESC)
AS RowNumber,
FirstName, LastName,
CONVERT(varchar(13), SUM(SalesAmountQuota),1) AS
SalesQuota
FROM dbo.DimEmployee AS e
INNER JOIN dbo.FactSalesQuota AS
sq
ON e.EmployeeKey = sq.EmployeeKey
WHERE e.SalesPersonFlag = 1
GROUP BY LastName, FirstName;
RowNumber FirstName
LastName
SalesQuota
--------- ---------
------------------
-------------
1 Jillian Carson 12,198,000.00
2 Linda Mitchell 11,786,000.00
3 Michael Blythe 11,162,000.00
4 Jae Pak 10,514,000.00
Using ROW_NUMBER() with PARTITION
shows using the
ROW_NUMBER function with the PARTITION BY argument. This causes the ROW_NUMBER function to number the rows in each partition.
-- Uses AdventureWorks
SELECT ROW_NUMBER() OVER(PARTITION BY SalesTerritoryKey
ORDER BY SUM(SalesAmountQuota) DESC) AS
RowNumber,
LastName, SalesTerritoryKey AS
Territory,
CONVERT(varchar(13), SUM(SalesAmountQuota),1) AS
SalesQuota
FROM dbo.DimEmployee AS e
INNER JOIN dbo.FactSalesQuota AS sq
ON e.EmployeeKey = sq.EmployeeKey
WHERE e.SalesPersonFlag = 1
GROUP BY LastName, FirstName, SalesTerritoryKey;
RowNumber LastName Territory SalesQuota
--------- ------------------ ---------
-------------
1 Campbell 1 4,025,000.00
2 Ansman-Wolfe 1 3,551,000.00
3 Mensa-Annan 1 2,275,000.00
1 Blythe 2 11,162,000.00
1 Carson 3 12,198,000.00
1 Mitchell 4 11,786,000.00
2 Ito 4 7,804,000.00
No comments:
Post a Comment