min with over,without group by:返回意外结果

时间:2013-06-10 13:41:36

标签: sql sql-server-2012 aggregate-functions

我有以下查询:

SELECT      ContractNr
,           SequenceNr
,           DurationBeginDate 
,           MIN(DurationBeginDate) OVER(PARTITION BY contractnr ORDER BY SEQUENCENR ASC) mindurdat
FROM        AccountContract
WHERE       ContractNr = 768

返回以下结果:

ContractNr  SequenceNr DurationBeginDate            mindurdat
768         1          2008-03-08 00:00:00.0000000  2008-03-08 00:00:00.0000000
768         2          2008-06-08 00:00:00.0000000  2008-03-08 00:00:00.0000000
768         3          2008-09-08 00:00:00.0000000  2008-03-08 00:00:00.0000000
768         4          2008-12-08 00:00:00.0000000  2008-03-08 00:00:00.0000000
768         5          2007-06-08 00:00:00.0000000  2007-06-08 00:00:00.0000000

这不是我的预期,我想要的mindurdat字段是与最低DurationBeginDate对应的SequenceNr。换句话说,对于所有这些记录,它应该是2008-03-08 00:00:00.0000000 我不明白为什么此示例中的最后一条记录保留原始DurationBeginDate

我知道我可以通过子查询获得正确的结果,但我希望保持高效。

1 个答案:

答案 0 :(得分:0)

当您在总和,分钟,最大值等中使用order by时,您将得到一个正在运行的聚合。所以它正在完成它的设计目标。您可以使用子查询或联接执行所需操作:

-- Join
SELECT
    ac.ContractNr
    , ac.SequenceNr
    , ac.DurationBeginDate 
    , ao.DurationBeginDate FirstDurationBegin
FROM
    AccountContract ac
LEFT JOIN
    accountcontract ao
    ON 
        ao.contractnr = ac.contractnr
        AND 
        ao.sequencenr = 1
WHERE
    ac.ContractNr = 768

-- outer apply
SELECT
    ac.ContractNr
    , ac.SequenceNr
    , ac.DurationBeginDate 
    , aor.DurationBeginDate FirstDurationBegin
FROM
    AccountContract ac
OUTER APPLY
    (
        SELECT 
            ao.DurationBeginDate
        FROM 
            AccountContract ao
        WHERE
            ao.contractnr = ac.contractnr
            AND 
            ao.sequencenr = 1
    ) aor
WHERE
    ac.ContractNr = 768