通过SQL PARTITION选择最新项目

时间:2017-09-21 18:48:20

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

注意:我正在尝试学习窗口函数,所以当我可以使用GROUP BY执行此操作时 - 我明确地开始使用窗口函数

我有以下测试结果表

| Id | TargetId | TestId | ResultId | TestedOn                 |
+----+----------+--------+----------+--------------------------+
| 1  | 1        | 1      | 5        | 9/1/2017 6:28:32.220 PM  |
| 2  | 1        | 2      | 5        | 9/1/2017 6:28:32.220 PM  |
| 3  | 1        | 3      | 5        | 9/1/2017 6:28:32.220 PM  |
| 4  | 1        | 1      | 4        | 9/10/2017 6:28:32.220 PM |
| 5  | 1        | 2      | 4        | 9/10/2017 6:28:32.220 PM |
| 6  | 1        | 3      | 5        | 9/10/2017 6:28:32.220 PM |

我想为每个测试ID选择最新结果 - 所以我有以下内容:

SELECT DISTINCT
    TargetId,
    TestId,
    FIRST_VALUE(tr.ResultId) OVER (PARTITION BY TestId ORDER BY TestedOn DESC) LatestResultId
FROM 
    TestResult tr

我得到了预期的结果

| TargetId | TestId | LatestResultId |
+----------+--------+----------------+
| 1        | 1      | 4              |
| 1        | 2      | 4              |
| 1        | 3      | 5              |

我不明白为什么这个查询,而不是使用FIRST_VALUE,我使用LAST_VALUE并相应地排序,但这会产生不同的结果。

SELECT DISTINCT
    TargetId, 
    TestId,
    LAST_VALUE(tr.ResultId) OVER (PARTITION BY TestId ORDER BY TestedOn) LatestResultId
FROM  
    TestResult tr


| TargetId | TestId | LatestResultId |
+----------+--------+----------------+
| 1        | 1      | 4              |
| 1        | 1      | 5              |
| 1        | 2      | 4              |
| 1        | 2      | 5              |
| 1        | 3      | 5              |
| 1        | 3      | 5              |

对我来说,这些查询应该产生相同的结果集。

2 个答案:

答案 0 :(得分:5)

尝试添加:

OVER (PARTITION BY TestId ORDER BY TestedOn
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)

我认为升序窗口函数的默认值是:

ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

https://docs.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql

答案 1 :(得分:0)

你可以使用with子句,

的行
WITH N(TESTID,LATEST_DATE) AS

(SELECT DISTINCT TestId, Max(TestedOn ) OVER(PARTITION BY TestId) FROM TestResult)

Select TestId, ResultId from FROM TestResult TR join N ON TR.TestId = N.TESTID AND TR.TestedOn =N.LATEST_DATE

表'N'只是一个临时表,其中包含TestID和LATEST_DATE

列表