sql - Teradata выбрать записи для группы на основе условия - PullRequest
0 голосов
/ 15 марта 2019

вход:

| cust_no | month_nr | resource| segment |
|---------|----------|---------|---------|
|       1 | jan-18    | r3     | s1      |
|       1 | feb-18    | r4     | s1      |
|       1 | mar-18    | r2     | s1      |
|       1 | apr-18    | r3     | s1      |
|       1 | jun-18    | r7     | s1      |
|       2 | may-18    | r4     | s2      |
|       2 | jun-18    | r2     | s2      |
|       2 | aug-18    | r3     | s3      |
|       2 | sep-18    | r2     | s4      |
|       2 | oct-18    | r4     | s4      |
|       2 | nov-18    | r1     | s4      |
|       3 | sep-18    | r7     | s2      |
|       3 | oct-18    | r9     | s1      |
|       3 | nov-18    | r2     | s3      |


expect output:
| cust_no | month_nr | resource| segment |
|---------|----------|---------|---------|
|       1 | jan-18    | r3     | s1      |
|       2 | may-18    | r4     | s2      |
|       2 | jun-18    | r2     | s2      |
|       2 | aug-18    | r3     | s3      |
|       2 | sep-18    | r2     | s4      |
|       3 | sep-18    | r7     | s2      |
|       3 | oct-18    | r9     | s1      |
|       3 | nov-18    | r2     | s3      |

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

  • клиент 1 имеет 5 продолжений сегмента s1: сохраняйте выходные данные 1-го ряда клиента 1;
  • у клиента 2 есть 3 продолжения сегмента s4: сохранить первую строку сегмента s4; И сохранить сегмент s2 (2 раза непрерывно) и сегмент s3 (1 раз) неизменными в выходе
  • записи клиента 3 остаются одинаковыми в выходных данных, поскольку значения сегментов не остаются непрерывно одинаковыми более 2 раз.

Есть предложения?

1 Ответ

0 голосов
/ 15 марта 2019

Я вполне уверен, что teradata поддерживает оконные функции.Этот запрос должен создать набор строк, который представляет собой только те строки, которые вы хотите удалить, т. Е. Для каждого клиента, только строки, в которых предыдущие ДВЕ строки имеют тот же сегмент, что и текущая строка.Вы можете изменить его на запрос на удаление, который «удаляет, где столбец первичного ключа отсутствует в»:

SELECT cust_no, month_nr, resource, segment
FROM 
  (
    SELECT 
      *, 
      LAG(segment, 1) OVER(PARTITION BY cust_no ORDER BY cast(month_nr as DATE FORMAT 'mmm-yy') as prevsegment,
      LAG(segment, 2) OVER(PARTITION BY cust_no ORDER BY cast(month_nr as DATE FORMAT 'mmm-yy') as prevprevsegment,
      LEAD(segment, 1) OVER(PARTITION BY cust_no ORDER BY cast(month_nr as DATE FORMAT 'mmm-yy') as nextsegment
    FROM table
  ) a
WHERE
  (segment = prevsegment AND segment = prevprevsegment) OR
  (segment = prevsegment AND segment = nextsegment)

Запрос просматривает текущий сегмент и сравнивает его с предыдущим и предыдущим предыдущим сегментом (я будуназовите это «правилом двух предыдущих»).Он также сравнивает текущий с предыдущим и следующим (я назову это «правилом любой стороны»)

Для последовательности сегментов, таких как: 1,2,2,3,3,3,4, 4,4,4

Вот как работает логика:

1 - don't touch
2 - don't touch
2 - don't touch
3 - don't touch
3 - remove because of Either Side rule
3 - remove because of Previous Two rule
4 - don't touch
4 - either side
4 - either side
4 - previous two

И т. Д.

Следовательно, этот запрос возвращает строки, которые необходимо удалить, каквы не будете использовать это как упражнение, потому что я не знаю, какой у вас первичный ключ

Единственное, в чем я не уверен, так это в том, что делает teradata, если вы пытаетесь преобразовать бездневную строку даты в дату.Возможно, вам придется объединить '01 - 'в ваш month_nr и настроить формат даты.Не храните даты в виде строк!Даже это, где вы хотите только месяц, должен был быть сохранен как ДАТА, где каждый день был 01

...