Границы диапазона оконной функции Spark SQL с условием - PullRequest
2 голосов
/ 16 января 2020

Мои данные выглядят следующим образом:

         Sequence|       type      | sg       |
+-----------------+----------------+----------+
|              1| Pump             |3         |
|              2| Pump             |2         |
|              3| Inject           |4         |
|              4| Pump             |5         |
|              5| Pump             |3         | 
|              6| pump             |6         |
|              7| Inject           |7         |
|              8| Inject           |8         |
|              9| Pump             |9         |
+-----------------+----------------+----------+

Я хочу добавить новый столбец и проверить предыдущее значение type.

Если предыдущее значение type равно Pump, установите значение нового столбца равным значению соответствующего sg.

Если это inject, то получите сумму значений sg всех предыдущих строк до строки с Pump type найдено (его значение sg включено в сумму).

EX: Для Sequence = 2 * * * * * * * * * * * * * * * * *, тогда предыдущий ряд равен Pump, поэтому новый столбец значение должно соответствовать значению соответствующего столбца sg: 3.

Для Sequence = 9 значение type предыдущей строки равно Inject, поэтому значение нового столбца будет суммой трех предыдущих строк ' sg столбец, поскольку Sequence = 6 строка является первой предыдущей строкой с type = Pump. Значение нового столбца будет тогда 8 + 7 + 6 = 21.

Окончательный результат должен быть таким:

       Sequence|       type      | sg       |  New sg |
+-----------------+----------------+----------+--------+
|              1| Pump             |3         |-
|              2| Pump             |2         |3
|              3| Inject           |4         |2
|              4| Pump             |5         |6
|              5| Pump             |3         |5
|              6| pump             |6         |3
|              7| Inject           |7         |6
|              8| Inject           |8         |7
|              9| Pump             |9         |21
+-----------------+----------------+----------+

1 Ответ

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

Исходя из ваших правил, это всего лишь набор оконных функций. Хитрость заключается в агрегировании по группам значений «насос» с «впрыскивать». Кумулятивная сумма "pump" s находит группы.

Тогда запрос:

select t.*,
        (case when prev_type = 'Pump' then sg
              else lag(pump_sg) over (order by id)
         end) as your_value
from (select t.*,
             sum(sg) over (partition by pump_grp) as pump_sg
      from (select t.*,
                   lag(sg) over (order by id) as prev_sg,
                   lag(type) over (order by id) as prev_type,
                 sum(case when type = 'Pump' then 1 else 0 end) over (order by id) as pump_grp
            from t
           ) t
     ) t;

Я думаю, что ваши правила слишком сложны, и вам не нужен особый случай для предыдущий ряд был "насосом". Итак:

select t.*,
       lag(pump_sg) over (order by id) as your_value
from (select t.*,
             sum(sg) over (partition by pump_grp) as pump_sg
      from (select t.*,
                 sum(case when type = 'Pump' then 1 else 0 end) over (order by id) as pump_grp
            from t
           ) t
     ) t;
...