Стандартный SQL имеет синтаксис для этого:
SELECT LAG(previous_reference_no IGNORE NULLS) OVER (ORDER BY createdon)
FROM TableA
К сожалению, SQL Server не поддерживает это. Один метод использует два уровня оконных функций и некоторую логику:
SELECT (CASE WHEN previous_reference_no IS NULL
THEN MAX(prev_reference_no) OVER (PARTITION BY grp)
ELSE LAG(previous_reference_no) OVER (PARTITION BY (CASE WHEN previous_reference_no IS NOT NULL THEN 1 ELSE 0 END)
ORDER BY createdon)
END)
FROM (SELECT a.*,
COUNT(prev_reference_no) OVER (ORDER BY a.createdon) as grp
FROM TableA a
) a;
Логика:
- Создайте группу, которая имеет заданный ссылочный номер и все следующие значения
NULL
в одной группе.
- Если ссылочный номер
NULL
, тогда получите первое значение для начала группы. Это будет предыдущее не NULL
значение.
- Если ссылочный номер не
NULL
, используйте partition by
для просмотра последнего не- NULL
значения.
Другой метод, который, вероятно, будет намного медленнее, использует APPLY
:
select a.*, aprev.prev_reference_no
from TableA a outer apply
(select top (1) aprev.*
from TableA aprev
where aprev.createdon < a.createdon and
aprev.prev_reference_no is not null
) aprev;
Для небольшой таблицы снижение производительности может стоить простоты кода.