使用MAX的SQL窗口函数没有给出预期的结果

时间:2015-08-11 20:10:45

标签: sql sql-server aggregate-functions

所以我在使用AdventureWorks 2012进行在线帮助教程后,正在使用SQL窗口函数。

我从以下查询中选择了数据到新表

select *,
MIN(Amount) OVER(Partition by AccountID order by transactionDate) AS     MinOrderForDate
from dbo.transactions
Order by AccountID, transactionID desc

然后我运行了以下查询:

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

这给了我预期的结果:

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

但是当我用MAX替换MIN时,我会继续在帐户的整个数据范围内获取MAX值,我不明白为什么?

load_and_authorize_resource

我这样做错了吗?

3 个答案:

答案 0 :(得分:2)

如果您使用非唯一列进行排序,则无法保证结果集。

在您的情况下,结果正是您所要求的,累积的MIN / MAX,由于ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,您的查询会自动添加ORDER BY。此外,窗口化聚合函数中的ORDER BY与最终ORDER BY不同,这会增加混淆。

您没有明确说明您想要获得的内容。根据列别名,您可能需要一个“组”MIN / MAX:

MIN(Amount) OVER(Partition by AccountID, transactionDate) AS     MinOrderForDate

答案 1 :(得分:1)

您对自己的意图并不十分明确,但听起来您希望每个min/max分组都account/transactionDate。如果是这种情况,您可能并不意味着将transactionDate放在窗口函数的order by子句中。

我认为你的意思是这样做:

MIN(Amount) OVER(Partition by AccountID, transactionDate) AS MinOrderForDate
MAX(Amount) OVER(Partition by AccountID, transactionDate) AS MaxOrderForDate

答案 2 :(得分:0)

您正在通过AccountID进行分区。它为您提供了该AccountID的MAX。对于AccountID 11000,MAX为3399,对于AccountID 11001,为3374。