LAST_VALUE() 究竟是如何工作的?
Posted
技术标签:
【中文标题】LAST_VALUE() 究竟是如何工作的?【英文标题】:How exactly LAST_VALUE() works? 【发布时间】:2020-01-25 00:43:57 【问题描述】:根据定义: LAST_VALUE() 函数是一个窗口函数,它返回结果集的有序分区中的最后一个值。
所以在我的示例中,我需要根据 QuoteID 获取最后一个 ExpirationDate 日期。
使用由QuoteID DESC
排序的FIRST_VALUE()
会产生正确的结果。
所以我期望使用由QuoteID ASC
订购的LAST_VALUE()
应该会产生相同的结果。
但是它给了我不正确的结果。
我错过了什么吗?
DECLARE @Table TABLE ( QuoteID int, PolicyNumber varchar(100), ExpirationDate date)
INSERT INTO @Table
(
QuoteID,
PolicyNumber,
ExpirationDate
)
VALUES
(
1, -- QuoteID - int
'Pol1', -- PolicyNumber - varchar
'2019-05-01' -- ExpirationDate - date
),
(
2, -- QuoteID - int
'Pol1', -- PolicyNumber - varchar
'2018-05-01' -- ExpirationDate - date
)
SELECT QuoteID, [@Table].ExpirationDate ,[@Table].PolicyNumber
,CAST(FIRST_VALUE(ExpirationDate) OVER (PARTITION BY PolicyNumber ORDER BY QuoteID DESC) AS DATE) as FIRST_VALUE_ExpirationDate --Correct
,CAST(LAST_VALUE(ExpirationDate) OVER (PARTITION BY PolicyNumber ORDER BY QuoteID ) AS DATE) as LAST_VALUE_ExpirationDate --Gives Incorrect
FROM @Table
ORDER BY QuoteID
【问题讨论】:
发布与您的结果相对应的示例数据并解释其中的问题。 @Serdia 。 . .我一般使用first_value()
,因为last_value()
有一些怪癖。
【参考方案1】:
LAST_VALUE 上的每个文档:
默认范围是“RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT 行”。
并且该范围内的 LAST_VALUE 始终是当前行
所以改成:
DECLARE @Table TABLE ( QuoteID int, PolicyNumber varchar(5), ExpirationDate date)
INSERT INTO @Table
(
QuoteID,
PolicyNumber,
ExpirationDate
)
VALUES
(
1, -- QuoteID - int
'Pol1', -- PolicyNumber - varchar
'2019-05-01' -- ExpirationDate - date
),
(
2, -- QuoteID - int
'Pol1', -- PolicyNumber - varchar
'2018-05-01' -- ExpirationDate - date
)
SELECT QuoteID, t.ExpirationDate ,t.PolicyNumber
,FIRST_VALUE(ExpirationDate)
OVER (PARTITION BY PolicyNumber
ORDER BY QuoteID DESC) as FIRST_VALUE_ExpirationDate
,LAST_VALUE(ExpirationDate)
OVER (PARTITION BY PolicyNumber
ORDER BY QuoteID ASC
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
) as LAST_VALUE_ExpirationDate
FROM @Table t
ORDER BY QuoteID
哪些输出:
QuoteID ExpirationDate PolicyNumber FIRST_VALUE_ExpirationDate LAST_VALUE_ExpirationDate
----------- -------------- ------------ -------------------------- -------------------------
1 2019-05-01 Pol1 2018-05-01 2018-05-01
2 2018-05-01 Pol1 2018-05-01 2018-05-01
【讨论】:
【参考方案2】:您的代码得到了正确的结果。
first_value
中的降序 order by
将 2018-05-01 保持在顶部,然后再将其选为第一个值。使用last_value
,升序的order by
将2019-05-01 保持在底部,因此您的last_value
将其选为最后一个值。
【讨论】:
以上是关于LAST_VALUE() 究竟是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章
bufferedReader() 在 Kotlin 中究竟是如何工作的?