Use of OVER CLAUSE with Aggregate function to make Analytic Function in Sql Server

Rajnilari2015
Posted by in Sql Server category on for Beginner level | Points: 250 | Views : 232 red flag

In this article, we will look into an example of the use of OVER CLAUSE with Aggregate function to make Analytic Function in Sql Server.


 Download source code for Use of OVER CLAUSE with Aggregate function to make Analytic Function in Sql Server

Introduction

Analytic function is a function which behaves very similar to an aggregate function with the exception that for each aggregated set, aggregate function returns one last but an analytic function returns intermediate results also.

It is done by adding the OVER keyword along with PARTITION BY and ORDER BY. the PARTITION BY clause is use for grouping the records while the presence of ORDER BY ensures the sorted order of occurrence of the intermediate rows.

In this article, we will look into an example of the use of OVER CLAUSE with Aggregate function to make Analytic Function

Let us consider a scenario where "Agents" has been asked to collect money and the report should contain the "Total Amount Collected" by the "Agent" with the "Highest" and "Lowest" amount received.

Let us look into what the problem is stating - say we have the Raw input data generated by using the following SQL script

Declare @T Table(AgentName Varchar(20),CollectedAmount Decimal)
Insert Into @T Values
('AgentName1',123.56)
,('AgentName1',153.56)
,('AgentName1',223.56)
,('AgentName1',3.46)
,('AgentName1',1256.96)
,('AgentName1',556.10)
,('AgentName1',534.56)
,('AgentName1',999.78)
,('AgentName1',638.00)
,('AgentName2',789.00)
,('AgentName2',666.56)
,('AgentName2',88.45)
,('AgentName2',663.46)
,('AgentName2',256.00)
,('AgentName2',456.67)

SELECT 	*
FROM @T

The final output should appear as

Solution

We propose the below solution for the aforementioned problem

SELECT 
		AgentName
		,[Total Amount Collected]
		,[Highest Amount Collected]
		,[Lowest Amount Collected]
FROM(
		SELECT 
			*
			,Rn=ROW_NUMBER() OVER(PARTITION BY AgentName ORDER BY CollectedAmount DESC)
			,[Total Amount Collected] = SUM(CollectedAmount) OVER(PARTITION BY AgentName ORDER BY (SELECT 1))
			,[Highest Amount Collected] = MAX(CollectedAmount) OVER(PARTITION BY AgentName ORDER BY (SELECT 1))
			,[Lowest Amount Collected] = MIN(CollectedAmount) OVER(PARTITION BY AgentName ORDER BY (SELECT 1))
		FROM @T
	)X
Where X.Rn=1

Let us try to understand what the inner query

SELECT 
			*
			,Rn=ROW_NUMBER() OVER(PARTITION BY AgentName ORDER BY CollectedAmount DESC)
			,[Total Amount Collected] = SUM(CollectedAmount) OVER(PARTITION BY AgentName ORDER BY (SELECT 1))
			,[Highest Amount Collected] = MAX(CollectedAmount) OVER(PARTITION BY AgentName ORDER BY (SELECT 1))
			,[Lowest Amount Collected] = MIN(CollectedAmount) OVER(PARTITION BY AgentName ORDER BY (SELECT 1))
		FROM @T

is doing.

Upon executing the inner query, we receive

The ROW_NUMBER() function provides the ranking. The records are PARTITION BY "AgentName" and the ORDER BY ensures the ordering of records within the partition by "CollectedAmount" in descending order.

The SUM function is basically an aggregated function. But with the presence of OVER Clause it acts as Analytic Function. In this case, we are performing a summation of "CollectedAmount" PARTITION BY "AgentName". The sorting is performed by using ORDER BY over "SELECT 1". The presence of "SELECT 1" will return the same number of rows. We can use any other value like "SELECT NULL", "SELECT GETDATE()", "SELECT 2" etc. to get the same result. It's a kind of dummy column which guarantees that the record ordering will not change which would otherwise change had it been done on some existing column.

The same applies for MAX and MIN function.

Now our objective is to pick up those records where Rn=1 which we have done in the outer query

SELECT 
		AgentName
		,[Total Amount Collected]
		,[Highest Amount Collected]
		,[Lowest Amount Collected]
FROM(
		SELECT 
			*
			.................
			.................
			.................
		FROM @T
	)X
Where X.Rn=1 -> Ensures we receive the latest record of the "CollectedAmount" for every Agent.

Conclusion

This article taught us how use OVER CLAUSE with Aggregate function to make Analytic Function. Hope this will be helpful. Thanks for reading. Zipped file is attached herewith.

Page copy protected against web site content infringement by Copyscape

About the Author

Rajnilari2015
Full Name: Niladri Biswas (RNA Team)
Member Level: Platinum
Member Status: Member,Microsoft_MVP,MVP
Member Since: 3/17/2015 2:41:06 AM
Country: India
-- Thanks & Regards, RNA Team


Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)