SQL Server: как получить предыдущее значение строки, используя LAG с определенным условием - PullRequest
3 голосов
/ 10 апреля 2019

Я хочу, чтобы в новом столбце всегда отображалось значение Price предыдущей записи, где Type не равен NULL. Пока что я согласен с текущим результатом, за исключением последней строки, которая показывает значение 2 строк ранее. Последняя строка должна отображать 0,666 вместо 1,66.

Я использую пример, который я нашел здесь, и добавил еще несколько строк, чтобы проверить, всегда ли он работает должным образом для моих целей.

Мои данные больше, чем в примере, и могут содержать несколько записей, где Тип не равен нулю. Кажется, что если group_nbr вернет те же числа, что и другие группы, это вызовет проблему ...

Я использую SQL Server 2017:

DECLARE @a TABLE ( number int, price money, type varchar(2),
                   date date, time time)
INSERT @a VALUES
(23454,1.50, NULL,'2014/02/02','07:00:02'),
(23455,1.60, NULL,'2014/02/02','07:05:02'),
(23456,0.665,'SV','2014/02/02','07:50:48'),
(23457,1.3  ,NULL,'2014/02/02','07:50:45'),
(23658,2.4  ,NULL,'2014/02/02','07:50:47'),
(23660,2.4  ,NULL,'2014/02/02','07:50:49'),
(23465,0.668,'SV','2014/02/02','07:50:46'),
(23467,0.666,'SV','2014/02/02','08:50:40'),
(23668,1.4  ,NULL,'2014/02/02','09:50:49'),
(23466,1.66, NULL,'2014/02/02','08:36:34');

; WITH a AS 
(
     SELECT 
         *,
         ROW_NUMBER() OVER (ORDER BY [date], [time] ) x, 
         ROW_NUMBER() OVER (PARTITION BY CASE WHEN [type] IS NOT NULL THEN 1 ELSE 0 END ORDER BY [date], [time]) y 
     FROM 
         @a
), b AS 
(
     SELECT 
         *,
         x - y as group_nbr,
         ROW_NUMBER() OVER(PARTITION BY x-y ORDER BY x ASC) z1 
     FROM
         a
)
SELECT 
    *,
    CASE 
       WHEN [type] IS NOT NULL 
          THEN LAG(price, z1) OVER (PARTITION BY [type] ORDER BY x) 
          ELSE LAG(price, z1) OVER (ORDER BY x) 
    END
FROM
    b
ORDER BY 
    x

Последняя запись должна возвращать 0,666 вместо 1,66.

Выходные данные всегда должны возвращать предыдущее значение Price для строк, в которых тип не равен нулю.

1 Ответ

3 голосов
/ 10 апреля 2019

Попробуйте это:

WITH DataSource as
(
    SELECT *
      ,COUNT(type) OVER (ORDER BY [date], [time] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)  - MAX(IIF(type is null, 0, 1)) OVER (ORDER BY [date], [time] ROWS BETWEEN 0 FOLLOWING AND 0 FOLLOWING) groupID
    FROM @a
), Groups (groupID, value) AS
(
    SELECT groupID
          ,MAX(IIF(type is not null, price, NULL))
    FROM DataSource
    GROUP BY groupID
)
SELECT *
FROM DataSource A
LEFT JOIN Groups B
    ON A.groupID = B.[groupID] + 1

enter image description here

Идея состоит в том, чтобы разделить строки на группы, а затем получить цену для какой группы (которая будет ценой, в которой type не равен нулю. Затем просто присоединитесь к таблицам и получите price предыдущей группы. .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...