Как я могу использовать функцию LAG и вернуть то же значение, если последующее значение в строке дублируется? - PullRequest
0 голосов
/ 24 мая 2019

Я использую функцию LAG, чтобы переместить мои значения на одну строку вниз.

Однако мне нужно использовать то же значение, что и в предыдущем случае, если элементы в столбце источника дублированы:

ID  |  SOURCE | LAG  | DESIRED OUTCOME

1   |    4    |  -   |   -

2   |    2    |  4   |   4

3   |    3    | 2    |   2

4   |    3    | 3    |   2  

5   |    3    | 3    |   2

6   |    1    | 3    |   3

7   |    4    | 1    |   1

8   |    4    | 4    |   1

Как вы можете видеть, например, в диапазоне ID 3-5 источникаданные не меняются, и требуемый результат должен подаваться из последней строки с другим значением (поэтому в этом случае ID 2 ).

Ответы [ 2 ]

0 голосов
/ 24 мая 2019

Ну, первое отставание не может быть инструментом для работы. Это может быть легче решить с помощью рекурсивного CTE. Sql и оконные функции работают над множеством. Тем не менее, наша цель здесь состоит в том, чтобы придумать способ описания того, что мы хотим. Мы хотели бы разделить наши данные так, чтобы последовательные острова одного и того же значения были частью одного набора.

Один из способов сделать это - использовать lag, чтобы помочь нам определить, был ли предыдущий ряд другим или нет. Оттуда теперь мы можем иметь промежуточную сумму по этим событиям изменения для создания разделов. Когда у нас есть разделы, мы можем назначить номер строки каждому элементу в разделе. Наконец, когда у нас есть это, мы можем теперь использовать номер строки, чтобы посмотреть
назад, что много элементов.

;with d as (
select * from (values
 (1,4)
,(2,2)
,(3,3)
,(4,3)
,(5,3)
,(6,1)
,(7,4)
,(8,4)
)f(id,source))
select *,lag(source,rn) over (order by Id)
from (
    select *,rn=row_number() over (partition by partition_id order by id)
    from (
        select *, partition_id = sum(change) over (order by id)
        from (
            select *,change = iif(lag(source) over (order by id) != source,1,0)
            from d
        ) source_with_change
    ) partitioned
) row_counted

Кстати, это абсолютно жестокий вопрос для собеседования, который мне когда-то задавали.

0 голосов
/ 24 мая 2019

Версия lag сервера Sql поддерживает выражение во втором аргументе для определения количества строк, которые нужно просмотреть. Вы можете заменить это какой-то проверкой, чтобы не оглядываться назад, например

select lagged = lag(data,iif(decider < 0,0,1)) over (order by id)
from (values(0,1,'dog')
            ,(1,2,'horse')
            ,(2,-1,'donkey')
            ,(3,2,'chicken')
            ,(4,23,'cow'))f(id,decider,data)

Возвращает следующий список

null
dog
donkey
donkey
chicken

Поскольку значение decider в строке с id из 2 было отрицательным.

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