正在 SQL PARTITION 中选择最新项目
Selecting latest item over a SQL PARTITION
注意:我正在尝试学习 window 函数,所以虽然我可以使用 GROUP BY 来做到这一点 - 我明确打算使用 window 函数
我有以下table的测试结果
| 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 |
我想 select 每个测试 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 |
对我来说,这些查询应该产生相同的结果集。
尝试添加:
OVER (PARTITION BY TestId ORDER BY TestedOn
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
我认为升序 window 函数的默认值是:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
https://docs.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql
你可以使用 with clause 来做到这一点,类似于
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
Table 'N' 只是一个具有 TestID 和 LATEST_DATE
列表的临时 table
注意:我正在尝试学习 window 函数,所以虽然我可以使用 GROUP BY 来做到这一点 - 我明确打算使用 window 函数
我有以下table的测试结果
| 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 |
我想 select 每个测试 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 |
对我来说,这些查询应该产生相同的结果集。
尝试添加:
OVER (PARTITION BY TestId ORDER BY TestedOn
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
我认为升序 window 函数的默认值是:
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
https://docs.microsoft.com/en-us/sql/t-sql/queries/select-over-clause-transact-sql
你可以使用 with clause 来做到这一点,类似于
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
Table 'N' 只是一个具有 TestID 和 LATEST_DATE
列表的临时 table