OVER Clause (Transact-SQL)
SQL Server 2008 R2
Applies to:
Ranking window functions
Aggregate window functions. For more information, see Aggregate Functions (Transact-SQL).
Ranking Window Functions
< OVER_CLAUSE > :: =
OVER ( [ PARTITION BY value_expression ,
... [ n ] ]
<ORDER
BY_Clause> )
Aggregate Window Functions
< OVER_CLAUSE > :: =
OVER ( [ PARTITION BY value_expression ,
... [ n ] ] )
PARTITION
BY
Divides
the result set into partitions. The window function is applied to each
partition separately and computation restarts for each partition.
value_expression
Specifies
the column by which the rowset produced by the corresponding FROM clause is
partitioned. value_expression can only refer to
columns made available by the FROM clause. value_expression
cannot refer to expressions or aliases in the select list. value_expression can be a column expression, scalar
subquery, scalar function, or user-defined variable.
<ORDER
BY Clause>
Specifies
the order to apply the ranking window function. For more information, see ORDER BY
Clause (Transact-SQL).
|
|
|
When used
in the context of a ranking window function, <ORDER BY Clause> can only
refer to columns made available by the FROM clause. An integer cannot be
specified to represent the position of the name or alias of a column in the
select list. <ORDER BY Clause> cannot be used with aggregate window
functions.
|
More than one ranking or aggregate window function can be used in a single query with a single FROM clause. However, the OVER clause for each function can differ in partitioning and also ordering. The OVER clause cannot be used with the CHECKSUM aggregate function.
A. Using the OVER clause with the ROW_NUMBER function
Each ranking function,
ROW_NUMBER, DENSE_RANK, RANK, NTILE uses the OVER clause. The following example
shows using the OVER clause with ROW_NUMBER.
USE AdventureWorks2008R2;
GO
SELECT p.FirstName, p.LastName
,ROW_NUMBER() OVER(ORDER
BY SalesYTD DESC) AS 'Row Number'
,s.SalesYTD,
a.PostalCode
FROM Sales.SalesPerson s
INNER JOIN Person.Person
p
ON
s.BusinessEntityID = p.BusinessEntityID
INNER JOIN
Person.Address a
ON a.AddressID =
p.BusinessEntityID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0;
GO
B. Using the OVER clause with aggregate functions
The following examples show
using the OVER clause with aggregate functions. In this
example, using the OVER clause is more efficient than
using subqueries.
USE AdventureWorks2008R2;
GO
SELECT SalesOrderID, ProductID, OrderQty
,SUM(OrderQty)
OVER(PARTITION BY SalesOrderID) AS 'Total'
,AVG(OrderQty)
OVER(PARTITION BY SalesOrderID) AS 'Avg'
,COUNT(OrderQty)
OVER(PARTITION BY SalesOrderID) AS 'Count'
,MIN(OrderQty)
OVER(PARTITION BY SalesOrderID) AS 'Min'
,MAX(OrderQty)
OVER(PARTITION BY SalesOrderID) AS 'Max'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN(43659,43664);
GO
Here is the result set.|
SalesOrderID |
ProductID |
OrderQty |
Total |
Avg |
Count |
Min |
Max |
|
43659
|
776
|
1
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
777
|
3
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
778
|
1
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
771
|
1
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
772
|
1
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
773
|
2
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
774
|
1
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
714
|
3
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
716
|
1
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
709
|
6
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
712
|
2
|
26
|
2
|
12
|
1
|
6
|
|
43659
|
711
|
4
|
26
|
2
|
12
|
1
|
6
|
|
43664
|
772
|
1
|
14
|
1
|
8
|
1
|
4
|
|
43664
|
775
|
4
|
14
|
1
|
8
|
1
|
4
|
|
43664
|
714
|
1
|
14
|
1
|
8
|
1
|
4
|
|
43664
|
716
|
1
|
14
|
1
|
8
|
1
|
4
|
|
43664
|
777
|
2
|
14
|
1
|
8
|
1
|
4
|
|
43664
|
771
|
3
|
14
|
1
|
8
|
1
|
4
|
|
43664
|
773
|
1
|
14
|
1
|
8
|
1
|
4
|
|
43664
|
778
|
1
|
14
|
1
|
8
|
1
|
4
|
USE AdventureWorks2008R2;
GO
SELECT SalesOrderID, ProductID,
OrderQty
,SUM(OrderQty) OVER(PARTITION BY
SalesOrderID) AS 'Total'
,CAST(1. * OrderQty / SUM(OrderQty)
OVER(PARTITION BY SalesOrderID)
*100 AS DECIMAL(5,2))AS 'Percent by
ProductID'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID
IN(43659,43664);
GO
Here
is the result set. Notice that the aggregates are calculated by SalesOrderID and the Percent by ProductID
is calculated for each line of each SalesOrderID.|
SalesOrderID |
ProductID |
OrderQty |
Total |
Percent by ProductID |
|
43659
|
776
|
1
|
26
|
3.85
|
|
43659
|
777
|
3
|
26
|
11.54
|
|
43659
|
778
|
1
|
26
|
3.85
|
|
43659
|
771
|
1
|
26
|
3.85
|
|
43659
|
772
|
1
|
26
|
3.85
|
|
43659
|
773
|
2
|
26
|
7.69
|
|
43659
|
774
|
1
|
26
|
3.85
|
|
43659
|
714
|
3
|
26
|
11.54
|
|
43659
|
716
|
1
|
26
|
3.85
|
|
43659
|
709
|
6
|
26
|
23.08
|
|
43659
|
712
|
2
|
26
|
7.69
|
|
43659
|
711
|
4
|
26
|
15.38
|
|
43664
|
772
|
1
|
14
|
7.14
|
|
43664
|
775
|
4
|
14
|
28.57
|
|
43664
|
714
|
1
|
14
|
7.14
|
|
43664
|
716
|
1
|
14
|
7.14
|
|
43664
|
777
|
2
|
14
|
14.29
|
|
43664
|
771
|
3
|
14
|
21.43
|
|
43664
|
773
|
1
|
14
|
7.14
|
|
43664
|
778
|
1
|
14
|
7.14
|
No comments:
Post a Comment