The use of Over()

Hello,

I have a question about the following query.
I understand most parts of the following query, but I don't understand ' * 10000/count(*) Over() ' part.
Why would we multiply '1000/Count(*)'? and what does Over() do at the end of the query?

Select SalesPersonID, Sum(TotalDue) as TotalSales,
NTILe(10) Over (Order by Sum(TotalDue)) * 10000/Count(*) Over() as Bonus
from Sales.SalesOrderHeader
where SalesPersonID is not null
group by SalesPersonID
order by TotalSales;
IzzyTwinklyAsked:
Who is Participating?
 
dsackerContract ERP Admin/ConsultantCommented:
The COUNT(*) OVER() simply returns the count of rows in the entire result.

It seems the intent was to divide $10000 into bonuses, hence the 10000/COUNT(*) OVER(). The NTILE(10) would group the sales into 10 buckets, giving each bucket a larger piece of the pie based on sales. The problem is that their formula as a whole will probably result in a bit more than $10000, if you summed up the bonuses (afterwards).

If a company only has $10000 to dispense to its sales force, and wants to dispense based on buckets, this may work a little better.
;WITH BonusCTE AS
(
SELECT  SalesPersonID,
        SUM(TotalDue) AS TotalSales, 
        NTILE(10) OVER (ORDER BY SUM(TotalDue)) AS PieceOfPie
FROM    Sales.SalesOrderHeader
WHERE   SalesPersonID is not null
GROUP BY SalesPersonID
),
SumCTE AS
(
SELECT  SUM(PieceOfPie) AS SumPie
FROM    BonusCTE
)
SELECT  SalesPersonID,
        TotalSales,
        10000 * PieceOfPie / SumPie AS Bonus
FROM    BonusCTE, SumCTE
ORDER BY TotalSales DESC

Open in new window

Of course, if you're using the same AdventureWorks database I used in looking at this, I'd rather have the bonuses from your query. :)
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
Over() just says "all rows, ignoring group by". Without it, count(*) should only count within one group (SalesPersonID).
0
 
Scott PletcherSenior DBACommented:
I think the idea was, logically enough, to pay higher bonuses for higher-total sales, but never to exceed 10,000 per SalesPersonId.

The way the code does it is interesting and somewhat counter-intuitive, just because we are accustomed to seeing "top sales" reports from hi to low rather than low to hi.

NTILE(10) will always return a number between 1 and 10.  That number then gets multiplied by 10,000, and finally divided by the total number of groups.  Since sales are sorted low to high, higher sales will have higher NTILE(10) values and thus get higher bonuses, but the bonus can never exceed 10,000 per SalesPersonId (per row).
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
Vitor MontalvãoMSSQL Senior EngineerCommented:
IzzyTwinkly, do you still need help with this question?
0
 
dsackerContract ERP Admin/ConsultantCommented:
Hi Izzy, glad that helped.
0
 
IzzyTwinklyAuthor Commented:
Thanks dsacker!

It was a really big help!
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.