Как именно работает LAST_VALUE ()? - PullRequest
0 голосов
/ 25 января 2020

Согласно определению: Функция LAST_VALUE () - это оконная функция, которая возвращает последнее значение в упорядоченном разделе набора результатов.

Так что в моем примере мне нужно получить последняя дата ExpirationDate, основанная на QuoteID.

Использование FIRST_VALUE() в порядке QuoteID DESC дает правильный результат.

Так что я ожидаю, что использование LAST_VALUE(), заказанное QuoteID ASC, должно привести к тому же результату.

Однако это дает мне неверный результат.

Я что-то упустил?

  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

enter image description here

Ответы [ 2 ]

1 голос
/ 25 января 2020

Для документов в LAST_VALUE :

Диапазон по умолчанию - «ДИАПАЗОН МЕЖДУ НЕПРЕДУСМОТРЕННЫМ И ТЕКУЩИМ СТРОКОМ».

И 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
1 голос
/ 25 января 2020

Вы получаете правильный результат для своего кода.

Нисходящий order by в вашем first_value сохраняет 2018-05-01 наверху, прежде чем он выберет его в качестве первого значения. С last_value восходящий order by удерживает 2019-05-01 внизу, поэтому ваш last_value выбирает его как последнее значение.

...