Reputation: 21
So I'm playing around with SQL window functions following on-line help tutorials using AdventureWorks 2012.
I selected out data from the below query into a new table
SELECT sh.CustomerID AS AccountID,
sd.SalesOrderDetailID AS TransactionID,
sh.OrderDate AS TransactionDate,
sd.LineTotal AS Amount
INTO Transactions
FROM sales.SalesOrderHeader sh INNER JOIN sales.SalesOrderDetail sd on
sh.SalesOrderID = sd.SalesOrderID
Then I ran the following query:
select *,
MIN(Amount) OVER(Partition by AccountID order by transactionDate) AS MinOrderForDate
from dbo.transactions
Order by AccountID, transactionID desc
Which gave me my expected result:
AccountID TransactionID TransactionDate Amount MinOrderForDate
11000 63804 2007-11-04 00:00:00.000 53.990000 4.990000
11000 63803 2007-11-04 00:00:00.000 34.990000 4.990000
11000 63802 2007-11-04 00:00:00.000 4.990000 4.990000
11000 63801 2007-11-04 00:00:00.000 28.990000 4.990000
11000 63800 2007-11-04 00:00:00.000 2384.070000 4.990000
11000 38716 2007-07-22 00:00:00.000 21.980000 21.980000
11000 38715 2007-07-22 00:00:00.000 2319.990000 21.980000
11000 449 2005-07-22 00:00:00.000 3399.990000 3399.990000
11001 115673 2008-06-12 00:00:00.000 34.990000 4.990000
11001 115672 2008-06-12 00:00:00.000 8.990000 4.990000
11001 115671 2008-06-12 00:00:00.000 4.990000 4.990000
11001 115670 2008-06-12 00:00:00.000 539.990000 4.990000
11001 38639 2007-07-20 00:00:00.000 8.990000 4.990000
11001 38638 2007-07-20 00:00:00.000 53.990000 4.990000
11001 38637 2007-07-20 00:00:00.000 9.990000 4.990000
11001 38636 2007-07-20 00:00:00.000 4.990000 4.990000
11001 38635 2007-07-20 00:00:00.000 21.980000 4.990000
11001 38634 2007-07-20 00:00:00.000 2319.990000 4.990000
11001 423 2005-07-18 00:00:00.000 3374.990000 3374.990000
But when I replaced MIN with MAX, I keep on getting the MAX value across the whole data range for the account and I can't see why?
select *,
MAX(Amount) OVER(Partition by AccountID order by transactionDate) AS MaxOrderForDate
from dbo.transactions
Order by AccountID, transactionID desc
AccountID TransactionID TransactionDate Amount MaxOrderForDate
11000 63804 2007-11-04 00:00:00.000 53.990000 3399.990000
11000 63803 2007-11-04 00:00:00.000 34.990000 3399.990000
11000 63802 2007-11-04 00:00:00.000 4.990000 3399.990000
11000 63801 2007-11-04 00:00:00.000 28.990000 3399.990000
11000 63800 2007-11-04 00:00:00.000 2384.070000 3399.990000
11000 38716 2007-07-22 00:00:00.000 21.980000 3399.990000
11000 38715 2007-07-22 00:00:00.000 2319.990000 3399.990000
11000 449 2005-07-22 00:00:00.000 3399.990000 3399.990000
11001 115673 2008-06-12 00:00:00.000 34.990000 3374.990000
11001 115672 2008-06-12 00:00:00.000 8.990000 3374.990000
11001 115671 2008-06-12 00:00:00.000 4.990000 3374.990000
11001 115670 2008-06-12 00:00:00.000 539.990000 3374.990000
11001 38639 2007-07-20 00:00:00.000 8.990000 3374.990000
11001 38638 2007-07-20 00:00:00.000 53.990000 3374.990000
11001 38637 2007-07-20 00:00:00.000 9.990000 3374.990000
11001 38636 2007-07-20 00:00:00.000 4.990000 3374.990000
11001 38635 2007-07-20 00:00:00.000 21.980000 3374.990000
11001 38634 2007-07-20 00:00:00.000 2319.990000 3374.990000
11001 423 2005-07-18 00:00:00.000 3374.990000 3374.990000
Am I doing this wrong?
Upvotes: 0
Views: 140
Reputation: 60462
If you order by a non-unique column there's no guaranteed result set.
In your case the result is exactly what you request, a cumulative MIN/MAX, there's a ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
automatically added to your query due to the ORDER BY
. Additionally the ORDER BY
in the Windowed Aggregate Function differs from the final ORDER BY
which adds more confusion.
You didn't specify exactly what you're trying to get. Based on the column alias you might want a "group" MIN/MAX:
MIN(Amount) OVER(Partition by AccountID, transactionDate) AS MinOrderForDate
Upvotes: 2
Reputation: 36483
You are not very explicit about your intent, but it sounds like you want the min/max
for each account/transactionDate
grouping. If that's the case, you probably didn't mean to put transactionDate
in the order by
clause of the window function.
I think you meant to do this instead:
MIN(Amount) OVER(Partition by AccountID, transactionDate) AS MinOrderForDate
MAX(Amount) OVER(Partition by AccountID, transactionDate) AS MaxOrderForDate
Upvotes: 1
Reputation: 3470
You are partitioning by AccountID. It's giving you the MAX for that AccountID. For AccountID 11000 the MAX is 3399, for AccountID 11001 it is 3374.
Upvotes: 0